MHEG5  18.9.0
MHEG5 Documentation
mg_hkfont.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2012 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
38 /*---includes for this file--------------------------------------------------*/
39 #include <stdio.h>
40 #ifdef HK_PROFILE
41 #include <string.h>
42 
43 #include <ft2build.h>
44 #include FT_FREETYPE_H
45 
46 #include "mg_drawtext.h"
47 #include "mg_hkfont.h"
48 #include "glue_memory.h"
49 #include "glue_debug.h"
50 #include "mg_ctxt.h"
51 #include "mg_osd.h"
52 #include "osd_utils.h"
53 #include "stb_osd.h"
54 
55 #include "dvb_font.h"
56 
57 /*---constant definitions for this file--------------------------------------*/
58 
59 /* Unicode control characters: non-printable */
60 #define U_CTRL_NULL 0x00
61 #define U_CTRL_A 0x01
62 #define U_CTRL_B 0x02
63 #define U_CTRL_C 0x03
64 #define U_CTRL_D 0x04
65 #define U_CTRL_E 0x05
66 #define U_CTRL_F 0x06
67 #define U_CTRL_G 0x07
68 #define U_CTRL_H 0x08
69 #define U_CTRL_K 0x0B
70 #define U_CTRL_L 0x0C
71 #define U_CTRL_N 0x0E
72 #define U_CTRL_O 0x0F
73 #define U_CTRL_P 0x10
74 #define U_CTRL_Q 0x11
75 #define U_CTRL_R 0x12
76 #define U_CTRL_S 0x13
77 #define U_CTRL_T 0x14
78 #define U_CTRL_U 0x15
79 #define U_CTRL_V 0x16
80 #define U_CTRL_W 0x17
81 #define U_CTRL_X 0x18
82 #define U_CTRL_Y 0x19
83 #define U_CTRL_Z 0x1A
84 #define U_CTRL_FS 0x1C
85 #define U_CTRL_GS 0x1D
86 #define U_CTRL_RS 0x1E
87 #define U_CTRL_US 0x1F
88 
89 
90 /* Unicode character values */
91 #define UNICODE_SPACE (' ')
92 #define UNICODE_TAB ('\t')
93 #define UNICODE_LF (0x0a)
94 #define UNICODE_CR (0x0d)
95 #define UNICODE_ESC (0x1b)
96 #define UNICODE_HARD_SPACE (0xa0)
97 #define UNICODE_FIGURE_SPACE (0x2007)
98 #define UNICODE_APOSTROPHE_N (0x0149)
99 #define UNICODE_HYPER_ANCHOR_START (0x41)
100 #define UNICODE_HYPER_ANCHOR_END (0x61)
101 #define UNICODE_TEXT_COLOUR_START (0x43)
102 #define UNICODE_TEXT_COLOUR_END (0x63)
103 #define UNICODE_HYPER_ATTRIB_START (0x44)
104 #define UNICODE_HYPER_ATTRIB_END (0x64)
105 
106 /* HK profile: dont break after chars */
107 #define UNICODE_QUOTE ('"')
108 #define UNICODE_LEFT_ROUND ('(')
109 #define UNICODE_LEFT_SQUARE ('[')
110 #define UNICODE_LEFT_CURLY ('{')
111 #define UNICODE_LEFT_DQUOTE 0x201C
112 #define UNICODE_LEFT_PANGLE 0x2039
113 #define UNICODE_LEFT_FULL_CURLY 0xFF5B
114 #define UNICODE_LEFT_FULL_ROUND 0xFF08
115 #define UNICODE_LEFT_FULL_SQUARE 0xFF3B
116 #define UNICODE_LEFT_FULL_DROUND 0xFF5F
117 #define UNICODE_LEFT_FULL_DQUOTE 0xFF02
118 
119 /* HK profile: dont break before chars */
120 #define UNICODE_QUOTE ('"')
121 #define UNICODE_RIGHT_ROUND (')')
122 #define UNICODE_RIGHT_SQUARE (']')
123 #define UNICODE_RIGHT_CURLY ('}')
124 #define UNICODE_RIGHT_DQUOTE 0x201D
125 #define UNICODE_RIGHT_PANGLE 0x203A
126 #define UNICODE_RIGHT_FULL_CURLY 0xFF5D
127 #define UNICODE_RIGHT_FULL_ROUND 0xFF09
128 #define UNICODE_RIGHT_FULL_SQUARE 0xFF3D
129 #define UNICODE_RIGHT_FULL_DROUND 0xFF60
130 #define UNICODE_RIGHT_FULL_DQUOTE 0xFF02
131 #define UNICODE_FULL_QUESTIONMARK 0xFF1F
132 #define UNICODE_QUESTIONMARK 0x003F
133 #define UNICODE_EXCLAMATIONMARK 0x0021
134 #define UNICODE_FULL_STOP ('.')
135 #define UNICODE_COMMA (',')
136 #define UNICODE_COMMA_FULL 0xFF0C
137 #define UNICODE_FULL_STOP_FULL 0xFF0E
138 #define UNICODE_COLON (':')
139 #define UNICODE_SEMICOLON (';')
140 #define UNICODE_FULL_SEMICOLON 0xFF1B
141 #define IDEOGRAPHIC_COMMA 0x3001
142 #define IDEOGRAPHIC_FULL_STOP 0x3002
143 
144 #define HIGH_SURROGATE_START 0xD800
145 #define HIGH_SURROGATE_END 0xDBFF
146 #define LOW_SURROGATE_START 0xDC00
147 #define LOW_SURROGATE_END 0xDFFF
148 #define FULL_ADVANCE 1
149 #define HALF_ADVANCE 2
150 #define NO_ADVANCE 3
151 
152 #if 0
153 #define DIV(x, y) ((((x) * 10) / (y) + 5) / 10)
154 #else
155 #define DIV(x, y) ((x) / (y))
156 #endif
157 
158 /* SD-HD scaling function, using the existing mg_context */
159 #define SCALE_X_TO_HD(X) DIV((X * mg_ctxt.osd_x.mlt), mg_ctxt.osd_x.div)
160 #define SCALE_Y_TO_HD(Y) DIV((Y * mg_ctxt.osd_y.mlt), mg_ctxt.osd_y.div)
161 
162 /* checks for breakable whitespace */
163 #define IS_WHITESPACE(X) ((X) == UNICODE_SPACE || (X) == UNICODE_TAB)
164 
165 #define SRC_FORE_MAX 255
166 #define FactorForeAlpha(fore_value, fore_col) fore_value *= (fore_col >> 24)
167 #define NotTransTDColor( col ) ((col >> 12) != 0x0)
168 #define NotOpaqueTDColor( col ) ((col >> 12) != 0xf)
169 
170 
171 /*---local typedef structs for this file-------------------------------------*/
172 
173 
174 typedef struct fontLibrary_s
175 {
176  FT_Library library;
177  FT_Face face;
178 } fontLibrary_t;
179 
180 typedef struct metrics_s
181 {
182  S32BIT fullAdvance;
183  S32BIT halfAdvance;
184  S32BIT xOffsetLeft;
185  S32BIT yMin;
186  S32BIT yMax;
187 } metrics_t;
188 
189 /* a character to be rendered */
190 typedef struct textChar_s
191 {
192  U32BIT uchar; /* The utf-16 character to print*/
193  U16BIT position; /* X position of the origin of the character */
194  U8BIT advanceType; /* whether the advance is full or half width*/
195  U32BIT advance; /* character advance in pixels*/
196  OSDColor colour; /* ARGB colour (per char) */
197  struct textChar_s *next; /* Next char on the line, NULL if last in line */
198  struct textChar_s *previous; /* Previous char on the line, NULL if first in the line */
199 } textChar_t;
200 
201 /* A line of characters */
202 typedef struct textLine_s
203 {
204  textChar_t *firstChar; /* first character item in line*/
205  textChar_t *lastChar; /* last character item in line*/
206  U16BIT fullCharCount; /* number of full-width chars */
207  U16BIT halfCharCount; /* number of half-width chars */
208  U16BIT position; /* Y position of the line */
209  struct textLine_s *next; /* Next line */
210  struct textLine_s *previous; /* previous line */
211  struct textItem_s *parentObject; /* pointer to the text object containing the line */
212 } textLine_t;
213 
214 /* justification function pointer prototype */
215 typedef void (*justify_fn)(struct textItem_s *textObject);
216 
217 /* parsed text data structure*/
218 typedef struct textItem_s
219 {
220  U32BIT boxX, boxY; /* text box dimensions */
221  S_SURFACE *canvas; /* surface and associated data */
222  justify_fn vJustify, hJustify; /* pointers to justification functions */
223  U16BIT *chars; /* original string */
224  U32BIT charsLen; /* length of the chars string */
225  U16BIT lineCount; /* number of lines created (CRs and wrapping) */
226  U16BIT maxLines; /* maximum displayable lines of text */
227  metrics_t *metrics; /* metic table for the required font size*/
228  pDrawTextAttrib attribs; /* attributes of the text object */
229  textLine_t *firstLine; /* pointer to the first line */
230  textLine_t *lastLine; /* pointer to the last line */
231 } textItem_t;
232 
233 /* structure to build a stack of colours for markup */
234 typedef struct colourNode_s
235 {
236  OSDColor colour;
237  struct colourNode_s *previous;
238 } colourNode_t;
239 
240 
241 /*---local (static) variable declarations for this file----------------------*/
242 
243 static fontLibrary_t *font = NULL;
244 static colourNode_t *colourStack = NULL;
245 
246 /*metrics taken from the profile specification*/
247 static metrics_t metrics24Point = {22, 11, 1, -3, 18};
248 static metrics_t metrics26Point = {24, 12, 1, -3, 20};
249 static metrics_t metrics31Point = {28, 14, 1, -4, 23};
250 static metrics_t metrics36Point = {32, 16, 2, -4, 27};
251 
252 static U16BIT overwrite_caret = ENTRY_OVERWRITE_CHAR;
253 static U16BIT insert_caret = ENTRY_INSERT_CHAR;
254 /*---local function definitions----------------------------------------------*/
255 
256 /*---global function definitions---------------------------------------------*/
257 
258 
263 static void DestructColourStack(void)
264 {
265  colourNode_t *previous;
266  while (colourStack != NULL)
267  {
268  previous = colourStack->previous;
269  STB_MemFree(colourStack);
270  colourStack = previous;
271  }
272 }
273 
279 static void InitColourStack(OSDColor colour)
280 {
281  if (colourStack != NULL)
282  {
283  DestructColourStack();
284  }
285  colourStack = STB_MemAlloc(sizeof(colourNode_t));
286  colourStack->previous = NULL;
287  colourStack->colour = colour;
288 }
289 
295 static void PushColour(OSDColor colour)
296 {
297  colourNode_t *new;
298  new = STB_MemAlloc(sizeof(colourNode_t));
299  new->previous = colourStack;
300  new->colour = colour;
301  colourStack = new;
302 }
303 
310 static OSDColor PopColour(void)
311 {
312  colourNode_t *previous;
313  if (colourStack->previous != NULL)
314  {
315  previous = colourStack->previous;
316  STB_MemFree(colourStack);
317  colourStack = previous;
318  }
319  return colourStack->colour;
320 }
321 
328 static U16BIT* ReadHyperAttribs(U16BIT *string, pHyperAttribs ha)
329 {
330  U16BIT tagLength;
331  U16BIT bytesLeft;
332  U16BIT *cursor = string;
333  BOOLEAN linkColourEnabled = FALSE;
334  BOOLEAN activeColourEnabled = FALSE;
335  BOOLEAN visitedColourEnabled = FALSE;
336  if ((ha != NULL))
337  {
338  /*move to the tag length byte*/
339  cursor++;
340  tagLength = *cursor;
341  bytesLeft = tagLength;
342  if (bytesLeft >= 2)
343  {
344  cursor += 2;
345  if (((*cursor) & 0x08) != 0)
346  {
347  ha->anchor_wrap = TRUE;
348  }
349  else
350  {
351  ha->anchor_wrap = FALSE;
352  }
353 
354  if (((*cursor) & 0x40) != 0)
355  {
356  linkColourEnabled = TRUE;
357  }
358  if (((*cursor) & 0x20) != 0)
359  {
360  activeColourEnabled = TRUE;
361  }
362  if (((*cursor) & 0x10) != 0)
363  {
364  visitedColourEnabled = TRUE;
365  }
366  bytesLeft -= 2;
367  }
368  if (bytesLeft >= 4 && linkColourEnabled)
369  {
370  ha->link_colour = RGBT(cursor[0], cursor[1], cursor[2], cursor[3]);
371  cursor += 4;
372  bytesLeft -= 4;
373  }
374  if (bytesLeft >= 4 && activeColourEnabled)
375  {
376  ha->active_colour = RGBT(cursor[0], cursor[1], cursor[2], cursor[3]);
377  cursor += 4;
378  bytesLeft -= 4;
379  }
380  if (bytesLeft >= 4 && visitedColourEnabled)
381  {
382  ha->visit_colour = RGBT(cursor[0], cursor[1], cursor[2], cursor[3]);
383  cursor += 4;
384  bytesLeft -= 4;
385  }
386  }
387  /*return the end position: original + tag length + 1*/
388  return string + tagLength + 1;
389 }
390 
397 static U16BIT* AddHyperAnchor(U16BIT *string, pHyperAttribs ha)
398 {
399  U16BIT *cursor = string;
400  if ((ha != NULL))
401  {
402  ha->number_of_links++;
403  if (ha->markup_state == 0)
404  {
405  ha->markup_state = 2;
406  }
407  else
408  {
409  ha->markup_state++;
410  }
411  if (ha->focus_position == ha->number_of_links)
412  {
413  PushColour(ha->active_colour);
414  }
415  else
416  {
417  PushColour(ha->link_colour);
418  }
419  /*move to the tag length byte*/
420  cursor++;
421  /*move forward [tag length] bytes*/
422  cursor += (*cursor);
423  }
424  return cursor;
425 }
426 
433 static void EndHyperAnchor(U16BIT *string, pHyperAttribs ha)
434 {
435  if ((ha != NULL))
436  {
437  PopColour();
438  }
439 }
440 
447 static void ScaleAllToHD(textItem_t *textObject)
448 {
449  textLine_t *currentLine;
450  textChar_t *currentChar;
451 
452  /*scale the text box dimensions*/
453  textObject->boxX = SCALE_X_TO_HD(textObject->boxX);
454  textObject->boxY = SCALE_Y_TO_HD(textObject->boxY);
455 
456  /*go through each line*/
457  currentLine = textObject->firstLine;
458  while (currentLine != NULL)
459  {
460  /* scale each line position */
461  currentLine->position = SCALE_Y_TO_HD(currentLine->position);
462  /* go through each character */
463  currentChar = currentLine->firstChar;
464  while (currentChar != NULL)
465  {
466  /* scale each character position */
467  currentChar->position = SCALE_X_TO_HD(currentChar->position);
468  currentChar = currentChar->next;
469  }
470  currentLine = currentLine->next;
471  }
472 }
473 
479 static textChar_t* NewCharacter(U32BIT *pCharacter)
480 {
481  textChar_t *newChar;
482  newChar = STB_MemAlloc(sizeof(textChar_t));
483  if (newChar != NULL)
484  {
485  newChar->uchar = *pCharacter;
486  newChar->next = NULL;
487  }
488  return newChar;
489 }
490 
496 static textLine_t* NewLine(textItem_t *parent)
497 {
498  textLine_t *newLine;
499 
500  newLine = STB_MemAlloc(sizeof(textLine_t));
501  if (newLine != NULL)
502  {
503  newLine->firstChar = NULL;
504  newLine->lastChar = NULL;
505  newLine->fullCharCount = 0;
506  newLine->halfCharCount = 0;
507  newLine->next = NULL;
508  newLine->parentObject = parent;
509  /* add the new line to the end of the text object */
510  if (parent->lastLine != NULL)
511  {
512  parent->lastLine->next = newLine;
513  newLine->previous = parent->lastLine;
514  }
515  else
516  {
517  newLine->previous = NULL;
518  }
519  /*set it as the new lastLine in the object*/
520  parent->lastLine = newLine;
521  parent->lineCount++;
522  }
523  return newLine;
524 }
525 
532 static void DeleteChar(textChar_t *pChar, textLine_t *line)
533 {
534  if (pChar->advanceType == FULL_ADVANCE)
535  {
536  line->fullCharCount--;
537  }
538  else if (pChar->advanceType == HALF_ADVANCE)
539  {
540  line->halfCharCount--;
541  }
542  STB_MemFree(pChar);
543 }
544 
551 static void DeleteRemainingChars(textChar_t *pChar, textLine_t *line)
552 {
553  textChar_t *cursor, *next;
554 
555  cursor = pChar;
556  if (pChar->previous != NULL)
557  {
558  pChar->previous->next = NULL;
559  }
560 
561  while (cursor != NULL)
562  {
563  next = cursor->next;
564  DeleteChar(cursor, line);
565  cursor = next;
566  }
567 }
568 
574 static void DestructLine(textLine_t *line)
575 {
576  DeleteRemainingChars(line->firstChar, line);
577  STB_MemFree(line);
578 }
579 
585 static void DestructTextObject(textItem_t *text)
586 {
587  textLine_t *cursor, *next;
588 
589  cursor = text->firstLine;
590  while (cursor != NULL)
591  {
592  next = cursor->next;
593  DestructLine(cursor);
594  cursor = next;
595  }
596  STB_MemFree(text);
597 }
598 
606 static BOOLEAN CharIsPrintable(U16BIT uchar, int characterSet)
607 {
608  BOOLEAN print;
609  /*if we are using the HK character set*/
610  if (characterSet == 12)
611  {
612  /*if the value is higher than the highest value control character
613  it is "printable" (for now)*/
614  if (uchar > U_CTRL_US)
615  {
616  print = TRUE;
617  }
618  else
619  {
620  print = FALSE;
621  }
622  }
623  else /*UK character set*/
624  {
625  /* only allow latin characters*/
626  if (uchar > U_CTRL_US && uchar < 0x2000)
627  {
628  print = TRUE;
629  }
630  else
631  {
632  print = FALSE;
633  }
634  }
635  return print;
636 }
637 
644 static U32BIT PointsToPixels(U32BIT points, pDrawTextAttrib attribs)
645 {
646  U32BIT pixels;
647  switch (attribs->font.fp.style)
648  {
649  case FONT_STYLE_PLAIN:
650  pixels = (points * 45) / 56;
651  break;
652  case FONT_STYLE_SQUARE:
653  pixels = (points * 45) / 64;
654  break;
655  }
656  return pixels;
657 }
658 
664 static U32BIT GetLineLengthPixels(textLine_t *line)
665 {
666  U32BIT lineLengthPts;
667  U32BIT letterSpaces;
668  U32BIT charsWidth;
669  textItem_t *text;
670  U32BIT fullCharCount = line->fullCharCount;
671  U32BIT halfCharCount = line->halfCharCount;
672 
673  text = line->parentObject;
674 
675  letterSpaces = DIV(((fullCharCount + halfCharCount - 1) * text->attribs->letter_space), 255);
676 
677  charsWidth = ((fullCharCount * text->metrics->fullAdvance) + (halfCharCount * text->metrics->halfAdvance));
678 
679  lineLengthPts = charsWidth + letterSpaces + text->metrics->xOffsetLeft;
680 
681  /*test suite converts points to pixels 1:1*/
682 #if 1
683  return lineLengthPts;
684 #else
685  U32BIT lineLengthPixels;
686  lineLengthPixels = PointsToPixels(lineLengthPts, line->parentObject->attribs);
687  return lineLengthPixels;
688 #endif
689 }
690 
697 static BOOLEAN IsBreakable(U16BIT character)
698 {
699  BOOLEAN isBreakable;
700  if (character >= 0xF900 && character <= 0xFAFF)
701  isBreakable = TRUE;
702  else if (character >= 0x3190 && character <= 0x319F)
703  isBreakable = TRUE;
704  else if (character >= 0x4E00 && character <= 0x9FFF)
705  isBreakable = TRUE;
706  else if (character >= 0x3200 && character <= 0x32FF)
707  isBreakable = TRUE;
708  else
709  isBreakable = FALSE;
710  return isBreakable;
711 }
712 
719 static BOOLEAN DontBreakBefore(U16BIT character)
720 {
721  switch (character)
722  {
723  case UNICODE_QUOTE:
724  case UNICODE_RIGHT_ROUND:
725  case UNICODE_RIGHT_SQUARE:
726  case UNICODE_RIGHT_CURLY:
727  case UNICODE_RIGHT_DQUOTE:
728  case UNICODE_RIGHT_PANGLE:
729  case UNICODE_RIGHT_FULL_CURLY:
730  case UNICODE_RIGHT_FULL_ROUND:
731  case UNICODE_RIGHT_FULL_SQUARE:
732  case UNICODE_RIGHT_FULL_DROUND:
733  case UNICODE_RIGHT_FULL_DQUOTE:
734  case UNICODE_QUESTIONMARK:
735  case UNICODE_FULL_QUESTIONMARK:
736  case UNICODE_EXCLAMATIONMARK:
737  case UNICODE_FULL_STOP:
738  case UNICODE_COMMA:
739  case UNICODE_FULL_STOP_FULL:
740  case UNICODE_COMMA_FULL:
741  case UNICODE_COLON:
742  case UNICODE_SEMICOLON:
743  case UNICODE_FULL_SEMICOLON:
744  case UNICODE_HARD_SPACE:
745  case IDEOGRAPHIC_COMMA:
746  case IDEOGRAPHIC_FULL_STOP:
747  return TRUE;
748  default:
749  return FALSE;
750  }
751 }
752 
759 static BOOLEAN DontBreakAfter(U16BIT character)
760 {
761  switch (character)
762  {
763  case UNICODE_QUOTE:
764  case UNICODE_LEFT_ROUND:
765  case UNICODE_LEFT_SQUARE:
766  case UNICODE_LEFT_CURLY:
767  case UNICODE_LEFT_DQUOTE:
768  case UNICODE_LEFT_PANGLE:
769  case UNICODE_LEFT_FULL_CURLY:
770  case UNICODE_LEFT_FULL_ROUND:
771  case UNICODE_LEFT_FULL_SQUARE:
772  case UNICODE_LEFT_FULL_DROUND:
773  case UNICODE_LEFT_FULL_DQUOTE:
774  case UNICODE_HARD_SPACE:
776  return TRUE;
777  default:
778  return FALSE;
779  }
780 }
781 
787 static void DeleteFollowingWhitespace(textLine_t *line)
788 {
789  textChar_t *cursor;
790  cursor = line->lastChar;
791  while (IS_WHITESPACE(cursor->uchar))
792  {
793  cursor = cursor->previous;
794  }
795  if (cursor->next != NULL)
796  {
797  DeleteRemainingChars(cursor->next, line);
798  }
799 }
800 
807 static void DoWrapping(textItem_t *text)
808 {
809  textLine_t *currentLine;
810  textLine_t *newLine;
811  textChar_t *cursor;
812  BOOLEAN breakFound = FALSE;
813 
814  currentLine = text->lastLine;
815 
816  /*if the character goes over the box boundary*/
817  if (GetLineLengthPixels(currentLine) > text->boxX)
818  {
819  cursor = currentLine->lastChar;
820 
821  /*special case where a whitespace char takes the line over the limit*/
822  if (IS_WHITESPACE(cursor->uchar))
823  {
824  currentLine->lastChar = cursor->previous;
825  currentLine->lastChar->next = NULL;
826  DeleteChar(cursor, currentLine);
827  if (text->lineCount < text->maxLines)
828  {
829  NewLine(text);
830  }
831  cursor = NULL;
832  }
833  /*look for a breakpoint*/
834  while (!breakFound && cursor != NULL)
835  {
836  if (IS_WHITESPACE(cursor->uchar))
837  {
838  /*break after the whitespace if possible*/
839  if (cursor->next != NULL)
840  {
841  cursor = cursor->next;
842  }
843  breakFound = TRUE;
844  }
845  /*if current char is DBB or previous char was DBA*/
846  else if (DontBreakBefore(cursor->uchar) || DontBreakAfter(cursor->previous->uchar))
847  {
848  cursor = cursor->previous;
849  }
850  /*if the current or previous character is breakable */
851  else if (IsBreakable(cursor->uchar) || IsBreakable(cursor->previous->uchar))
852  {
853  breakFound = TRUE;
854  }
855  else
856  {
857  cursor = cursor->previous;
858  }
859  }
860 
861  if (breakFound)
862  {
863  /*put the characters after the breakpoint onto a new line*/
864  newLine = NewLine(text);
865  cursor->previous->next = NULL;
866  newLine->lastChar = currentLine->lastChar;
867  currentLine->lastChar = cursor->previous;
868  newLine->firstChar = cursor;
869  newLine->firstChar->previous = NULL;
870 
871  /*go through each character moved to the new line*/
872  for (cursor = newLine->firstChar; cursor != NULL; cursor = cursor->next)
873  {
874  /*move the character count for each onto the new line*/
875  if (cursor->advanceType == FULL_ADVANCE)
876  {
877  currentLine->fullCharCount--;
878  newLine->fullCharCount++;
879  }
880  else if (cursor->advanceType == HALF_ADVANCE)
881  {
882  currentLine->halfCharCount--;
883  newLine->halfCharCount++;
884  }
885  }
886 
887  DeleteFollowingWhitespace(currentLine);
888  }
889  }
890 }
891 
899 static void AddChar(U32BIT *character, textItem_t *text, OSDColor colour)
900 {
901  textLine_t *currentLine;
902  textChar_t *newChar;
903 
904  currentLine = text->lastLine;
905 
906  newChar = NewCharacter(character);
907  if (currentLine->firstChar == NULL)
908  {
909  currentLine->firstChar = newChar;
910  }
911  newChar->previous = currentLine->lastChar;
912  if (currentLine->lastChar != NULL)
913  {
914  currentLine->lastChar->next = newChar;
915  }
916  currentLine->lastChar = newChar;
917  newChar->colour = colour;
918 
919  if (*character < 0x1fff)
920  {
921  currentLine->halfCharCount++;
922  newChar->advanceType = HALF_ADVANCE;
923  newChar->advance = text->metrics->halfAdvance;
924  }
925  else
926  {
927  currentLine->fullCharCount++;
928  newChar->advanceType = FULL_ADVANCE;
929  newChar->advance = text->metrics->fullAdvance;
930  }
931 
932  if (text->attribs->justify & WRAP_WORDS)
933  {
934  DoWrapping(text);
935  }
936 }
937 
943 static void AddCaret(textItem_t *text)
944 {
945  textLine_t *currentLine;
946  textChar_t *newChar;
947  U32BIT *character;
948  currentLine = text->lastLine;
949 
950  /* Make 'character' point at global var */
951  switch (text->attribs->caret)
952  {
953  case ENTRY_INSERT_CHAR:
954  character = (U32BIT *)&insert_caret;
955  break;
957  character = (U32BIT *)&overwrite_caret;
958  break;
959  }
960 
961  newChar = NewCharacter(character);
962  if (currentLine->firstChar == NULL)
963  {
964  currentLine->firstChar = newChar;
965  }
966  newChar->previous = currentLine->lastChar;
967  if (currentLine->lastChar != NULL)
968  {
969  currentLine->lastChar->next = newChar;
970  }
971  currentLine->lastChar = newChar;
972  newChar->colour = text->attribs->fore_colour;
973 
974  if (text->attribs->entry_point == text->charsLen)
975  {
976  currentLine->halfCharCount++;
977  newChar->advanceType = HALF_ADVANCE;
978  newChar->advance = text->metrics->halfAdvance;
979  }
980  else
981  {
982  newChar->advanceType = NO_ADVANCE;
983  newChar->advance = 0;
984  }
985 
986  if (text->attribs->justify & WRAP_WORDS)
987  {
988  DoWrapping(text);
989  }
990 }
991 
998 static void GetMaxLines(textItem_t *text)
999 {
1000  S32BIT Ymin, Ymax;
1001 
1002  Ymin = 0 - text->metrics->yMin;
1003  Ymax = text->metrics->yMax;
1004  text->maxLines = ((text->boxY - (Ymax + Ymin)) / text->attribs->line_space) + 1;
1005 
1006  return;
1007 }
1008 
1014 static void FillLines(textItem_t *text)
1015 {
1016  U16BIT *currentChar;
1017  OSDColor markupColour;
1018  U16BIT high_surrogate = 0;
1019  text->firstLine = NewLine(text);
1020  text->lastLine = text->firstLine;
1021 
1022  markupColour = text->attribs->fore_colour;
1023 
1024  /*go through the string and fill up the text object*/
1025  for (currentChar = text->chars; currentChar < text->chars + (text->charsLen); currentChar++)
1026  {
1027  if (*currentChar >= HIGH_SURROGATE_START && *currentChar <= HIGH_SURROGATE_END)
1028  {
1029  high_surrogate = *currentChar;
1030  continue;
1031  }
1032 
1033  if (high_surrogate && *currentChar >= LOW_SURROGATE_START && *currentChar <= LOW_SURROGATE_END)
1034  {
1035  /*following rules found on the unicode.org FAQ*/
1036  U32BIT X, U;
1037  U32BIT unicode_character;
1038 
1039  X = (high_surrogate & 0x3F) << 10 | (*currentChar & 0x3FF);
1040  U = ((high_surrogate >> 6) & 0x1F) + 1;
1041  unicode_character = (U << 16) | X;
1042 
1043  AddChar(&unicode_character, text, markupColour);
1044 
1045  high_surrogate = 0;
1046  continue;
1047  }
1048  else if (high_surrogate)
1049  {
1050  high_surrogate = 0;
1051  continue;
1052  }
1053  /*if the current position is the entry point*/
1054  if (currentChar - text->chars == text->attribs->entry_point)
1055  {
1056  /*add the caret*/
1057  AddCaret(text);
1058  }
1059 
1060  /*On carriage return character*/
1061  if (*currentChar == UNICODE_CR)
1062  {
1063  /*create new line*/
1064  NewLine(text);
1065  }
1066  /*on markup escape character*/
1067  else if (*currentChar == UNICODE_ESC)
1068  {
1069  /*check the markup code*/
1070  currentChar++;
1071  switch (*currentChar)
1072  {
1074  currentChar++;
1075  if (*currentChar == 4)
1076  {
1077  currentChar++;
1078  markupColour = (*currentChar << 16) & 0xff0000;
1079  currentChar++;
1080  markupColour |= (*currentChar << 8) & 0xff00;
1081  currentChar++;
1082  markupColour |= *currentChar & 0xff;
1083  currentChar++;
1084  markupColour |= ((255 - *currentChar) << 24) & 0xff000000;
1085  PushColour(markupColour);
1086  }
1087  break;
1089  markupColour = PopColour();
1090  break;
1092  currentChar = ReadHyperAttribs(currentChar, text->attribs->p_ha);
1093  break;
1095  currentChar = AddHyperAnchor(currentChar, text->attribs->p_ha);
1096  markupColour = colourStack->colour;
1097  break;
1099  EndHyperAnchor(currentChar, text->attribs->p_ha);
1100  markupColour = colourStack->colour;
1101  break;
1102  default:
1103  break;
1104  }
1105  }
1106  else if (CharIsPrintable(*currentChar, text->attribs->character_set))
1107  {
1108  U32BIT unicode_character = *currentChar;
1109  AddChar(&unicode_character, text, markupColour);
1110  }
1111  }
1112  if (text->attribs->entry_point == text->charsLen)
1113  {
1114  AddCaret(text);
1115  }
1116 }
1117 
1121 static void JustifyHStart(textItem_t *textObject)
1122 {
1123  textLine_t *currentLine;
1124  textChar_t *currentChar;
1125  S32BIT cursor;
1126 
1127  currentLine = textObject->firstLine;
1128  while (currentLine != NULL)
1129  {
1130  currentChar = currentLine->firstChar;
1131  cursor = textObject->metrics->xOffsetLeft;
1132 
1133  while (currentChar != NULL)
1134  {
1135  currentChar->position = cursor;
1136  if (cursor + (S32BIT)currentChar->advance > (S32BIT)textObject->boxX)
1137  {
1138  currentLine->lastChar = currentChar->previous;
1139  DeleteRemainingChars(currentChar, currentLine);
1140  currentChar = NULL;
1141  break;
1142  }
1143  else
1144  {
1145  cursor += (S32BIT)currentChar->advance;
1146  currentChar = currentChar->next;
1147  }
1148  }
1149 
1150  currentLine = currentLine->next;
1151  }
1152 }
1153 
1157 static void JustifyHCentre(textItem_t *textObject)
1158 {
1159  textLine_t *currentLine;
1160  textChar_t *currentChar;
1161  S32BIT cursor;
1162  S32BIT lineLength;
1163 
1164  currentLine = textObject->firstLine;
1165  while (currentLine != NULL)
1166  {
1167  lineLength = GetLineLengthPixels(currentLine);
1168  cursor = ((S32BIT)textObject->boxX - lineLength) / 2;
1169  currentChar = currentLine->firstChar;
1170 
1171  while (currentChar != NULL)
1172  {
1173  currentChar->position = cursor;
1174  if (cursor + (S32BIT)currentChar->advance > (S32BIT)textObject->boxX)
1175  {
1176  currentLine->lastChar = currentChar->previous;
1177  DeleteRemainingChars(currentChar, currentLine);
1178  currentChar = NULL;
1179  break;
1180  }
1181  else if (cursor < textObject->metrics->xOffsetLeft)
1182  {
1183  currentLine->firstChar = currentChar->next;
1184  cursor += (S32BIT)currentChar->advance;
1185  DeleteChar(currentChar, currentLine);
1186  currentLine->firstChar->previous = NULL;
1187 
1188  currentChar = currentLine->firstChar;
1189  }
1190  else
1191  {
1192  cursor += (S32BIT)currentChar->advance;
1193  currentChar = currentChar->next;
1194  }
1195  }
1196 
1197  currentLine = currentLine->next;
1198  }
1199 }
1200 
1204 static void JustifyHEnd(textItem_t *textObject)
1205 {
1206  textLine_t *currentLine;
1207  textChar_t *currentChar;
1208  S32BIT cursor;
1209 
1210  currentLine = textObject->lastLine;
1211  while (currentLine != NULL)
1212  {
1213  currentChar = currentLine->lastChar;
1214  cursor = textObject->boxX - (S32BIT)currentChar->advance;
1215 
1216  while (currentChar != NULL)
1217  {
1218  currentChar->position = cursor;
1219  if (cursor < textObject->metrics->xOffsetLeft)
1220  {
1221  /*clever shuffling to delete unneeded chars*/
1222  currentChar = currentChar->next;
1223  currentChar->previous->next = NULL;
1224  DeleteRemainingChars(currentLine->firstChar, currentLine);
1225  currentLine->firstChar = currentChar;
1226  currentChar->previous = NULL;
1227  break;
1228  }
1229  else
1230  {
1231  currentChar = currentChar->previous;
1232  if (currentChar != NULL)
1233  {
1234  cursor -= (S32BIT)currentChar->advance;
1235  }
1236  }
1237  }
1238 
1239  currentLine = currentLine->previous;
1240  }
1241 }
1242 
1247 static void JustifyVStart(textItem_t *textObject)
1248 {
1249  textLine_t *currentLine;
1250  textLine_t *next;
1251  U32BIT cursor;
1252  U32BIT lineCount = 0;
1253  U32BIT yMaxPixels;
1254 
1255  /*calculate positions of lines*/
1256  currentLine = textObject->firstLine;
1257 
1258  yMaxPixels = textObject->metrics->yMax;
1259 
1260  cursor = yMaxPixels;
1261 
1262  /*slight correction for difference between font size and metrics*/
1263  cursor += 2;
1264  while (currentLine != NULL)
1265  {
1266  currentLine->position = cursor;
1267  cursor += textObject->attribs->line_space;
1268  lineCount++;
1269  if (lineCount > textObject->maxLines)
1270  {
1271  break;
1272  }
1273  else
1274  {
1275  currentLine = currentLine->next;
1276  }
1277  }
1278 
1279  if (currentLine != NULL)
1280  {
1281  currentLine->previous->next = NULL;
1282  while (currentLine != NULL)
1283  {
1284  next = currentLine->next;
1285  DestructLine(currentLine);
1286  currentLine = next;
1287  }
1288  }
1289 }
1290 
1295 static void JustifyVCentre(textItem_t *textObject)
1296 {
1297  textLine_t *currentLine;
1298  U32BIT cursor;
1299  U32BIT yMaxPixels, yMinPixels;
1300  U32BIT linesHeight;
1301 
1302  /*calculate positions of lines*/
1303  currentLine = textObject->firstLine;
1304 
1305  yMaxPixels = textObject->metrics->yMax;
1306  yMinPixels = 0 - textObject->metrics->yMin;
1307 
1308  linesHeight = yMaxPixels + yMinPixels + (textObject->attribs->line_space * (textObject->lineCount - 1));
1309  cursor = (textObject->boxY - linesHeight) / 2;
1310  cursor += yMaxPixels;
1311 
1312  while (currentLine != NULL)
1313  {
1314  currentLine->position = cursor;
1315  cursor += textObject->attribs->line_space;
1316  currentLine = currentLine->next;
1317  }
1318 }
1319 
1324 static void JustifyVEnd(textItem_t *textObject)
1325 {
1326  textLine_t *currentLine;
1327  U32BIT cursor;
1328  U32BIT yMinPixels;
1329 
1330  /*calculate positions of lines*/
1331  currentLine = textObject->lastLine;
1332 
1333  yMinPixels = 0 - textObject->metrics->yMin;
1334 
1335  cursor = textObject->boxY - yMinPixels;
1336 
1337  /*slight correction for difference between font size and metrics*/
1338  cursor -= 2;
1339 
1340  while (currentLine != NULL)
1341  {
1342  currentLine->position = cursor;
1343  cursor -= textObject->attribs->line_space;
1344  currentLine = currentLine->previous;
1345  }
1346 }
1347 
1353 static BOOLEAN CreateSurface(textItem_t *textObject)
1354 {
1355  BOOLEAN success = FALSE;
1356 
1357  textObject->canvas = STB_MemAlloc(sizeof(S_SURFACE));
1358  if (textObject->canvas != NULL)
1359  {
1361  {
1362  textObject->canvas->hw_handle = STB_OSDMhegCreateSurface(textObject->boxX,
1363  textObject->boxY,
1364  TRUE,
1365  MakeHD2Color(textObject->attribs->back_colour));
1366  }
1368  {
1369  textObject->canvas->hw_handle = STB_OSDMhegCreateSurface(textObject->boxX,
1370  textObject->boxY,
1371  TRUE,
1372  textObject->attribs->back_colour);
1373  }
1374 
1375  if (textObject->canvas->hw_handle != NULL)
1376  {
1377  textObject->canvas->width = textObject->boxX;
1378  textObject->canvas->height = textObject->boxY;
1379  success = TRUE;
1380  }
1381  }
1382 
1383  return success;
1384 }
1385 
1393 static void BlendColours32(OSDColor *pixel, U32BIT fore_value, OSDColor fore_col)
1394 {
1395  U32BIT fa, ba, comp, tmp_c, alpha_c;
1396  ba = *pixel >> 24;
1397 
1398  FactorForeAlpha(fore_value, fore_col);
1399 
1400  alpha_c = ((((255 ^ ba) * fore_value) + 32512) / 65025) + ba;
1401  fa = (U8BIT)(fore_value / SRC_FORE_MAX);
1402  ba = (((255 ^ fa) * ba) + 127) / 255;
1403  tmp_c = alpha_c << 24;
1404  comp = ba * ((*pixel >> 16) & 0xff) + fa * ((fore_col >> 16) & 0xff);
1405  tmp_c |= ((comp + (alpha_c >> 1)) / alpha_c) << 16;
1406  comp = ba * ((*pixel >> 8) & 0xff) + fa * ((fore_col >> 8) & 0xff);
1407  tmp_c |= ((comp + (alpha_c >> 1)) / alpha_c) << 8;
1408  comp = ba * (*pixel & 0xff) + fa * (fore_col & 0xff);
1409  tmp_c |= ((comp + (alpha_c >> 1)) / alpha_c);
1410  *pixel = tmp_c;
1411 }
1412 
1420 static void BlendColours16(HD2Color *pixel, U32BIT fore_value, OSDColor fore_col )
1421 {
1422  U32BIT fa, ba, comp, tmp_c, alpha_c;
1423  HD2Color temp_col = MakeHD2Color(fore_col);
1424 
1425  FactorForeAlpha(fore_value, fore_col);
1426  ba = *pixel >> 12;
1427  comp = ba * 17;
1428  alpha_c = ((((15 - ba) * fore_value) + 1912) / 3825) + comp;
1429  fa = (U8BIT)(fore_value / SRC_FORE_MAX);
1430  ba = (((255 ^ fa) * comp) + 127) / 255;
1431  tmp_c = (alpha_c / 17) << 12;
1432  comp = ba * ((*pixel >> 8) & 0xf) + fa * ((temp_col >> 8) & 0xf);
1433  tmp_c |= ((comp + (alpha_c >> 1)) / alpha_c) << 8;
1434  comp = ba * ((*pixel >> 4) & 0xf) + fa * ((temp_col >> 4) & 0xf);
1435  tmp_c |= ((comp + (alpha_c >> 1)) / alpha_c) << 4;
1436  comp = ba * (*pixel & 0xf) + fa * (temp_col & 0xf);
1437  tmp_c |= ((comp + (alpha_c >> 1)) / alpha_c);
1438  *pixel = tmp_c;
1439 }
1440 
1449 static void RenderChar(FT_GlyphSlot glyph, textLine_t *line, textChar_t *charObject)
1450 {
1451  S_SURFACE *canvas;
1452  U32BIT glyphHeight;
1453  U32BIT row_count;
1454  U32BIT a_point;
1455  U8BIT *src_buffer, *dest_buffer;
1456  S32BIT penX, penY;
1457  OSDColor fore_colour;
1458  U32BIT fore_value;
1459  U8BIT *src_pixel;
1460  OSDColor *dest_pixel;
1461 
1462  canvas = line->parentObject->canvas;
1463 
1464  glyphHeight = glyph->bitmap.rows;
1465 
1466  penX = charObject->position + glyph->bitmap_left;
1467  penY = line->position - glyph->bitmap_top;
1468 
1469  src_buffer = (U8BIT *)glyph->bitmap.buffer;
1470  dest_buffer = (U8BIT *)canvas->col_buff;
1471 
1472  fore_colour = charObject->colour;
1473  if (NotOpaqueTDColor( fore_colour ))
1474  {
1475  canvas->opaque = FALSE;
1476  }
1477  for (row_count = 0; row_count != glyphHeight && penY < canvas->height; row_count++)
1478  {
1479  if (penY < 0)
1480  {
1481  penY++;
1482  continue;
1483  }
1484 
1485  for (a_point = 0; a_point != glyph->bitmap.width && penX < canvas->width; a_point++)
1486  {
1487  if (penX < 0)
1488  {
1489  penX++;
1490  continue;
1491  }
1492  src_pixel = &src_buffer[(row_count * glyph->bitmap.pitch) + a_point];
1494  {
1495  dest_pixel = (OSDColor *)&dest_buffer[((penY * canvas->buff_pitch / 2) + (penX)) * 2];
1496  fore_value = *src_pixel;
1497  if (*src_pixel > 0)
1498  {
1499  BlendColours16((HD2Color *)dest_pixel, fore_value, fore_colour );
1500  }
1501  }
1503  {
1504  dest_pixel = (OSDColor *)&dest_buffer[((penY * canvas->buff_pitch / 4) + (penX)) * 4];
1505  fore_value = *src_pixel;
1506  if (*src_pixel > 0)
1507  {
1508  BlendColours32( dest_pixel, fore_value, fore_colour );
1509  }
1510  }
1511 
1512  penX++;
1513  }
1514  penX = charObject->position + glyph->bitmap_left;
1515  penY++;
1516  }
1517 }
1518 
1524 static BOOLEAN Render(textItem_t *textObject)
1525 {
1526  BOOLEAN success;
1527  textLine_t *currentLine;
1528  textChar_t *currentChar;
1529  S_SURFACE *canvas;
1530  FT_Error err;
1531  U32BIT fontWidth;
1532  U32BIT fontHeight;
1533 
1534  fontWidth = PointsToPixels(textObject->attribs->font.fp.size, textObject->attribs);
1535  fontHeight = textObject->attribs->font.fp.size;
1536 
1537  fontWidth = (fontWidth * mg_ctxt.osd_x.mlt) / mg_ctxt.osd_x.div;
1538  fontHeight = (fontHeight * mg_ctxt.osd_y.mlt) / mg_ctxt.osd_y.div;
1539 
1540  success = CreateSurface(textObject);
1541  if (success)
1542  {
1543  canvas = textObject->canvas;
1544  canvas->buff_pitch = textObject->boxX * 4;
1545  canvas->col_buff = STB_OSDMhegLockBuffer( canvas->hw_handle, &canvas->buff_pitch );
1546 
1547  FT_Set_Pixel_Sizes(font->face, fontWidth, fontHeight);
1548  }
1549  currentLine = textObject->firstLine;
1550 
1551  while (currentLine != NULL && success)
1552  {
1553  currentChar = currentLine->firstChar;
1554 
1555  while (currentChar != NULL && success)
1556  {
1557  /*load the required glyph from the font*/
1558  err = FT_Load_Char( font->face, currentChar->uchar, FT_LOAD_RENDER );
1559  if (!err)
1560  {
1561  RenderChar(font->face->glyph, currentLine, currentChar);
1562  }
1563  else
1564  {
1565  success = FALSE;
1566  }
1567  currentChar = currentChar->next;
1568  }
1569  currentLine = currentLine->next;
1570  }
1572  return success;
1573 }
1574 
1580 static fontLibrary_t* InitFreetype(pDrawTextAttrib attrib)
1581 {
1582  fontLibrary_t *newFontLibrary;
1583  FT_Error ftErr;
1584  E_MhegErr mhErr = MHERR_INTERNAL;
1585  S_FontData *fontFileData;
1586 
1587  newFontLibrary = STB_MemAlloc(sizeof(fontLibrary_t));
1588  if (newFontLibrary != NULL)
1589  {
1590  ftErr = FT_Init_FreeType( &newFontLibrary->library );
1591 
1592  if (ftErr)
1593  {
1594  STB_MemFree(newFontLibrary);
1595  newFontLibrary = NULL;
1596  }
1597  else
1598  {
1599  mhErr = DVB_MhegGetEmbeddedFont(attrib->font_name.zptr, &fontFileData);
1600  }
1601 
1602  if (mhErr == MHERR_OK && fontFileData != NULL)
1603  {
1604  if (fontFileData->dataType == MHEG5_FONT_FILE_PATH_TTF)
1605  {
1606  ftErr = FT_New_Face( newFontLibrary->library, (char *)fontFileData->data, 0, &newFontLibrary->face );
1607  }
1608  else if (fontFileData->dataType == MHEG5_RAW_FONT_DATA_TTF)
1609  {
1610  ftErr = FT_New_Memory_Face( newFontLibrary->library,
1611  (FT_Byte *)fontFileData->data,
1612  (FT_Long)fontFileData->dataLength,
1613  0,
1614  &newFontLibrary->face );
1615  }
1616  }
1617  else
1618  {
1619  STB_MemFree(newFontLibrary);
1620  newFontLibrary = NULL;
1621  }
1622 
1623  if (ftErr)
1624  {
1625  STB_MemFree(newFontLibrary);
1626  newFontLibrary = NULL;
1627  }
1628  }
1629  return newFontLibrary;
1630 }
1631 
1639 static textItem_t* InitText(const TextString unistr, pDrawTextAttrib attrib, const VRect txt_box)
1640 {
1641  textItem_t *newItem;
1642 
1643  newItem = STB_MemAlloc(sizeof(textItem_t));
1644  if (newItem != NULL)
1645  {
1646  switch (attrib->font.fp.size)
1647  {
1648  case 24:
1649  newItem->metrics = &metrics24Point;
1650  break;
1651  case 26:
1652  newItem->metrics = &metrics26Point;
1653  break;
1654  case 31:
1655  newItem->metrics = &metrics31Point;
1656  break;
1657  case 36:
1658  newItem->metrics = &metrics36Point;
1659  break;
1660  default:
1661  STB_MemFree(newItem);
1662  newItem = NULL;
1663  }
1664  }
1665  if (newItem != NULL)
1666  {
1667  newItem->firstLine = NULL;
1668  newItem->lastLine = NULL;
1669  newItem->lineCount = 0;
1670  newItem->chars = unistr.data;
1671  newItem->charsLen = unistr.len;
1672  newItem->attribs = attrib;
1673  newItem->boxX = txt_box.width;
1674  newItem->boxY = txt_box.height;
1675  /*set horizontal justification function*/
1676  switch (attrib->justify & JFY_HZ_MASK)
1677  {
1678  case JUSTIFY_H_START:
1679  case JUSTIFY_H_JUSTIFIED:
1680  newItem->hJustify = JustifyHStart;
1681  break;
1682  case JUSTIFY_H_END:
1683  newItem->hJustify = JustifyHEnd;
1684  break;
1685  case JUSTIFY_H_CENTRE:
1686  newItem->hJustify = JustifyHCentre;
1687  break;
1688  default:
1689  break;
1690  }
1691 
1692  switch (attrib->justify & JUSTIFY_VERTI_MASK)
1693  {
1694  case JUSTIFY_V_START:
1695  case JUSTIFY_V_JUSTIFIED:
1696  newItem->vJustify = JustifyVStart;
1697  break;
1698  case JUSTIFY_V_END:
1699  newItem->vJustify = JustifyVEnd;
1700  break;
1701  case JUSTIFY_V_CENTRE:
1702  newItem->vJustify = JustifyVCentre;
1703  break;
1704  default:
1705  break;
1706  }
1707  }
1708  return newItem;
1709 }
1710 
1719 void* MG_DrawHKText(const TextString unistr, pDrawTextAttrib attrib, const VRect txt_box)
1720 {
1721  textItem_t *textObject;
1722  S_SURFACE *renderedSurface = NULL;
1723  BOOLEAN success = FALSE;
1724 
1725  textObject = InitText(unistr, attrib, txt_box);
1726  if (font == NULL)
1727  {
1728  font = InitFreetype(attrib);
1729  }
1730 
1731  if (font == NULL)
1732  {
1733  return NULL;
1734  }
1735 
1736  GetMaxLines(textObject);
1737 
1738  InitColourStack(attrib->fore_colour);
1739  if (textObject != NULL)
1740  {
1741  FillLines(textObject);
1742  success = TRUE;
1743  }
1744  DestructColourStack();
1745 
1746  if (textObject != NULL && textObject->hJustify != NULL)
1747  {
1748  textObject->hJustify(textObject);
1749  }
1750  else
1751  {
1752  success = FALSE;
1753  }
1754 
1755  if (textObject != NULL && textObject->vJustify != NULL)
1756  {
1757  textObject->vJustify(textObject);
1758  }
1759  else
1760  {
1761  success = FALSE;
1762  }
1763  #if 0
1764  {
1765  textLine_t *line;
1766  textChar_t *character;
1767 
1768  DBG_PRINTF("debugging lines, justify = %x\n", attrib->justify);
1769  line = textObject->firstLine;
1770  while (line)
1771  {
1772  character = line->firstChar;
1773  while (character)
1774  {
1775  DBG_PRINTF("%x ", *character->uchar);
1776  character = character->next;
1777  }
1778  DBG_PRINTF("\n");
1779  line = line->next;
1780  }
1781  }
1782  #endif
1783 
1784  if (success)
1785  {
1786  ScaleAllToHD(textObject);
1787  success = Render(textObject);
1788  }
1789 
1790  if (success)
1791  {
1792  renderedSurface = textObject->canvas;
1793  }
1794  if (textObject != NULL)
1795  {
1796  DestructTextObject(textObject);
1797  }
1798 
1799  return renderedSurface;
1800 }
1801 
1802 #endif
OSD utility functions.
#define IF_COL_DEPTH(cd)
Definition: mg_ctxt.h:65
E_MhegErr DVB_MhegGetEmbeddedFont(const U8BIT *fontName, S_FontData **fontData)
Retrieves the specified embedded font. Depending on the requirements of the platform, it may either pass back:
#define RGBT(r, g, b, t)
Definition: tmcolor.h:48
#define FONT_STYLE_PLAIN
Definition: mg_drawtext.h:32
void * col_buff
Definition: mg_osd.h:41
U16BIT mlt
Definition: mg_ctxt.h:73
#define DBG_PRINTF(...)
Definition: glue_debug.h:127
#define JUSTIFY_H_JUSTIFIED
Definition: mg_drawtext.h:40
void STB_MemFree(void *ptr)
Releases previously allocated memory.
Debug tracing.
#define MakeHD2Color(osdcol)
Definition: osd_utils.h:56
U32BIT OSDColor
Definition: osdtypes.h:41
#define COLOUR_FORMAT_ARGB4444
Definition: mheg5_control.h:80
OSDColor link_colour
Definition: mg_drawtext.h:83
#define WRAP_WORDS
Definition: mg_drawtext.h:42
S_RATIO osd_y
Definition: mg_ctxt.h:86
OSDColor fore_colour
Definition: mg_drawtext.h:105
void * STB_OSDMhegCreateSurface(U16BIT width, U16BIT height, BOOLEAN init, U32BIT colour)
Creates a hardware surface on which MHEG5 engine will draw an individual MHEG object. At its basic the function can just allocate the buffer to be returned by STB_OSDMhegLockBuffer(). It&#39;s size being: (width * height * bytes_per_pixel) Also, when &#39;init&#39; is TRUE, function initialises surface buffer to the specified colour. For pixel colour format of less than four bytes, use least significant bits of &#39;colour&#39;.
#define JUSTIFY_V_CENTRE
Definition: mg_drawtext.h:52
U8BIT * zptr
Definition: dtvstring.h:31
E_MhegErr
Definition: mherrors.h:28
#define ENTRY_INSERT_CHAR
Definition: mg_drawtext.h:60
U8BIT style
Definition: mg_drawtext.h:99
#define UNICODE_TEXT_COLOUR_START
Definition: mg_drawtext.c:95
U32BIT buff_pitch
Definition: mg_osd.h:43
uint8_t U8BIT
Definition: techtype.h:82
U16BIT * data
Definition: mg_drawtext.h:77
U8BIT size
Definition: mg_drawtext.h:98
U32BIT dataLength
Definition: dvb_font.h:49
void * hw_handle
Definition: mg_osd.h:42
#define JUSTIFY_H_CENTRE
Definition: mg_drawtext.h:39
S_FontProp fp
Definition: mg_drawtext.h:116
Memory functions.
#define UNICODE_HYPER_ANCHOR_START
Definition: mg_drawtext.c:93
void * STB_MemAlloc(U32BIT memSize)
Allocates the specified number of bytes.
#define JUSTIFY_V_END
Definition: mg_drawtext.h:51
#define JUSTIFY_H_START
Definition: mg_drawtext.h:37
S_MGContext mg_ctxt
Definition: mg_osd.c:144
U16BIT height
Definition: mg_osd.h:40
Interface to OSD.
#define JFY_HZ_MASK
Definition: mg_drawtext.h:46
#define FONT_STYLE_SQUARE
Definition: mg_drawtext.h:33
#define ELSE
Definition: mg_ctxt.h:66
#define JUSTIFY_H_END
Definition: mg_drawtext.h:38
U8BIT anchor_wrap
Definition: mg_drawtext.h:90
U8BIT opaque
Definition: mg_osd.h:44
int32_t S32BIT
Definition: techtype.h:87
#define UNICODE_HYPER_ANCHOR_END
Definition: mg_drawtext.c:94
#define JUSTIFY_V_JUSTIFIED
Definition: mg_drawtext.h:53
OSDColor active_colour
Definition: mg_drawtext.h:84
#define UNICODE_CR
Definition: mg_drawtext.c:88
uint16_t U16BIT
Definition: techtype.h:84
U16BIT width
Definition: mg_osd.h:39
S_STRING font_name
Definition: mg_drawtext.h:118
Font loading functions required by MHEG5 engine (Hong Kong profile)
U16BIT len
Definition: mg_drawtext.h:76
#define ENTRY_OVERWRITE_CHAR
Definition: mg_drawtext.h:61
U16BIT height
Definition: mg_drawtext.h:70
#define JUSTIFY_V_START
Definition: mg_drawtext.h:50
OSDColor visit_colour
Definition: mg_drawtext.h:85
S16BIT focus_position
Definition: mg_drawtext.h:86
#define COLOUR_FORMAT_ARGB8888
Definition: mheg5_control.h:82
#define UNICODE_FIGURE_SPACE
Definition: mg_drawtext.c:91
#define FALSE
Definition: techtype.h:68
#define U_CTRL_US
Definition: mg_drawtext.c:82
#define UNICODE_HARD_SPACE
Definition: mg_drawtext.c:90
U8BIT * data
Definition: dvb_font.h:52
U16BIT div
Definition: mg_ctxt.h:74
S16BIT number_of_links
Definition: mg_drawtext.h:87
void * STB_OSDMhegLockBuffer(void *surface, U32BIT *pPitch)
Converts hardware surface handle returned by STB_OSDMhegCreateSurface() to buffer address that the en...
U16BIT width
Definition: mg_drawtext.h:69
U8BIT BOOLEAN
Definition: techtype.h:99
#define TRUE
Definition: techtype.h:69
#define UNICODE_ESC
Definition: mg_drawtext.c:89
Interface to the MHEG text render that uses Freetype font library.
#define JUSTIFY_VERTI_MASK
Definition: mg_drawtext.h:54
Interface to OSD.
#define UNICODE_HYPER_ATTRIB_START
Definition: mg_drawtext.c:97
U8BIT markup_state
Definition: mg_drawtext.h:89
#define UNICODE_TEXT_COLOUR_END
Definition: mg_drawtext.c:96
U16BIT HD2Color
Definition: osd_utils.h:70
E_FontDataType dataType
Definition: dvb_font.h:55
Interface to the MHEG text render that uses Freetype font library.
Graphics functions required by the HD MHEG5 engine. All references to colour used in these functions ...
S_RATIO osd_x
Definition: mg_ctxt.h:85
uint32_t U32BIT
Definition: techtype.h:86
void STB_OSDMhegUnlockBuffer(void *surface)
This function informs HW that MHEG5 is finished writing to the buffer.
union _DrawTextAttrib::@14 font