diff --git a/demo/converter_demo.c b/demo/converter_demo.c
index f921ad2..998188b 100644
--- a/demo/converter_demo.c
+++ b/demo/converter_demo.c
@@ -38,12 +38,15 @@ error_handler (HPDF_STATUS error_no,
int main (int argc, char **argv)
{
const wchar_t *HELLO =
- L"Hello.\x09 مرحبا.\u200F สวัสดี\x0A नमस्कार.\x0C "
- L"שלום.\u200F 안녕하세요.\x0D 你好。こんにちは。"
+ L"Hello.\x09 \uFFF9مرحبا.\u200F\uFFFAmarḥába\uFFFB สวัสดี\x0A नमस्कार.\x0C "
+ L"שלום.\u200F 안녕하세요.\x0D\uFFF9你好\uFFFAnǐhǎo\uFFFB。こんにちは。"
+ ;
+ const wchar_t *HELLO_ru =
+ L"Здравствуйте. "
;
const wchar_t *ONCE_UPON_A_TIME =
L"以前老夫婦が住んでいました。"
- L"老夫が山へ収穫に行きました。"
+ L"老夫が山へ\uFFF9収穫\uFFFAしばかり\uFFFBに行きました。"
L"老妻が川へ洗濯に行きました。\n"
L"老夫婦住。"
L"老丈夫去到了收穫的山。"
@@ -51,8 +54,8 @@ int main (int argc, char **argv)
L"老夫妇住。"
L"老丈夫去到了收获的山。"
L"老妻在河里去洗。\n"
- L"이전 노부부가 살고있었습니다. "
- L"늙은 남편이 산에 수확에갔습니다. "
+ L"이전 노부부가 살고있었습니다."
+ L"늙은 남편이 산에 수확에갔습니다."
L"늙은 아내가 강에 세탁갔습니다.\n"
L"Пожилая пара жила раньше. "
L"Старый муж пошел в урожай в горы. "
@@ -67,8 +70,8 @@ int main (int argc, char **argv)
L"Հին Ամուսինը գնաց բերքը լեռը. "
L"Հին կինը գնաց լվանում է գետը.\u200E\n"
L"عاش زوجين مسنين من قبل. "
- L"ذه\u0640ب الزوج القديم إلى الحص\u0640اد إلى الجبل. "
- L"زوجته البالغة من العمر ذه\u0640ب ليغسل في الن\u0640هر.\u200F\n"
+ L"ذهـب الزوج القديم إلى الحصـاد إلى الجبل. "
+ L"زوجته البالغة من العمر ذهـب ليغسل في النـهر.\u200F\n"
L"זוג קשישים חי בעבר. "
L"הבעל ישן הלך לקציר להר. "
L"אישה זקנה הלכה לרחוץ בנהר.\u200F\n"
@@ -83,24 +86,26 @@ int main (int argc, char **argv)
HPDF_Doc pdf;
char fname[256];
HPDF_Page page;
- HPDF_Font detail_font;
- HPDF_Font detail_font_v;
- HPDF_Font detail_font_v2;
+ HPDF_Font detail_font, detail_font_v, relief_font;
const char *detail_font_name;
- HPDF_Font relief_font;
- HPDF_REAL page_height;
- HPDF_REAL page_width;
+ HPDF_REAL page_width, page_height;
HPDF_UINT len;
HPDF_Rect rect;
+ HPDF_INT ttopt;
- if (1 < argc) {
- printf ("usage: converter_demo\n");
+ if (2 < argc || (1 < argc &&
+ (argv[1][0] != '-' || argv[1][1] != 'c' || argv[1][2] != 0))) {
+ printf ("usage: converter_demo [-c]\n");
return 1;
}
strcpy (fname, argv[0]);
strcat (fname, ".pdf");
+ ttopt = HPDF_FONTOPT_EMBEDDING;
+ if (1 < argc)
+ ttopt |= HPDF_FONTOPT_WITHOUT_CID_MAP;
+
pdf = HPDF_New (error_handler, NULL);
if (!pdf) {
printf ("error: cannot create PdfDoc object\n");
@@ -112,53 +117,54 @@ int main (int argc, char **argv)
return 1;
}
+ HPDF_SetCompressionMode (pdf, HPDF_COMP_IMAGE | HPDF_COMP_METADATA);
+
HPDF_UseCNSEncodings (pdf);
- HPDF_UseCNTEncodings (pdf);
- HPDF_UseJPEncodings (pdf);
+ //HPDF_UseCNTEncodings (pdf);
+ //HPDF_UseJPEncodings (pdf);
HPDF_UseKREncodings (pdf);
HPDF_UseUTFEncodings (pdf);
HPDF_UseCNSFonts (pdf);
- HPDF_UseCNTFonts (pdf);
- HPDF_UseJPFonts (pdf);
+ //HPDF_UseCNTFonts (pdf);
+ //HPDF_UseJPFonts (pdf);
HPDF_UseKRFonts (pdf);
- /* Korean */
- detail_font_name = HPDF_LoadTTFontFromFile2 (pdf,
- "C:\\Windows\\Fonts\\gulim.ttc", 1,
- HPDF_FONTOPT_EMBEDDING /* | HPDF_FONTOPT_WITH_CID_MAP */);
- detail_font = HPDF_GetFont (pdf, detail_font_name, "UTF-8");
+ /* Devanagari */
+ detail_font_name = HPDF_LoadTTFontFromFile (pdf,
+ "C:\\Windows\\Fonts\\mangal.ttf", ttopt);
+ detail_font = HPDF_GetFont (pdf, detail_font_name, "Ancient-UTF8-H");
+ detail_font_v = HPDF_GetFont (pdf, detail_font_name, "Ancient-UTF16-H");
- /* Simplified Chinese, Traditional Chinese, Japanese */
+ /* Thai, Armenian */
+ detail_font_name = HPDF_LoadTTFontFromFile (pdf,
+ "C:\\Windows\\Fonts\\tahoma.ttf", ttopt);
relief_font = detail_font;
- detail_font_name = HPDF_LoadTTFontFromFile2 (pdf,
- "C:\\Windows\\Fonts\\simsun.ttc", 1,
- HPDF_FONTOPT_EMBEDDING /* | HPDF_FONTOPT_WITH_CID_MAP */);
- detail_font = HPDF_GetFont (pdf, detail_font_name, "UTF-8");
+ detail_font = HPDF_GetFont (pdf, detail_font_name, "Ancient-UTF8-H");
HPDF_Font_SetReliefFont (detail_font, relief_font);
+ relief_font = detail_font_v;
+ detail_font_v = HPDF_GetFont (pdf, detail_font_name, "Ancient-UTF16-H");
+ HPDF_Font_SetReliefFont (detail_font_v, relief_font);
- /* Devanagari */
+ /* Korean */
+ detail_font_name = HPDF_LoadTTFontFromFile2 (pdf,
+ "C:\\Windows\\Fonts\\gulim.ttc", 1, ttopt);
relief_font = detail_font;
- detail_font_name = HPDF_LoadTTFontFromFile (pdf,
- "C:\\Windows\\Fonts\\mangal.ttf",
- HPDF_FONTOPT_EMBEDDING /* | HPDF_FONTOPT_WITH_CID_MAP */);
- detail_font = HPDF_GetFont (pdf, detail_font_name, "Ancient-UTF8-H");
+ detail_font = HPDF_GetFont (pdf, detail_font_name, "UniKS-UTF8-H");
HPDF_Font_SetReliefFont (detail_font, relief_font);
- /* Thai, Armenian */
+ /* Simplified Chinese, Traditional Chinese, Japanese */
+ detail_font_name = HPDF_LoadTTFontFromFile2 (pdf,
+ "C:\\Windows\\Fonts\\simsun.ttc", 1, ttopt);
relief_font = detail_font;
- detail_font_name = HPDF_LoadTTFontFromFile (pdf,
- "C:\\Windows\\Fonts\\tahoma.ttf",
- HPDF_FONTOPT_EMBEDDING /* | HPDF_FONTOPT_WITH_CID_MAP */);
- detail_font = HPDF_GetFont (pdf, detail_font_name, "Ancient-UTF8-H");
+ detail_font = HPDF_GetFont (pdf, detail_font_name, "UniGB-UTF8-H");
HPDF_Font_SetReliefFont (detail_font, relief_font);
/* Latin, Cyrillic, Greek, Arabic, Hebrew */
- relief_font = detail_font;
detail_font_name = HPDF_LoadTTFontFromFile (pdf,
- "C:\\Windows\\Fonts\\times.ttf",
- HPDF_FONTOPT_EMBEDDING /* | HPDF_FONTOPT_WITH_CID_MAP */);
+ "C:\\Windows\\Fonts\\times.ttf", ttopt);
+ relief_font = detail_font;
detail_font = HPDF_GetFont (pdf, detail_font_name, "Ancient-UTF8-H");
HPDF_Font_SetReliefFont (detail_font, relief_font);
@@ -166,38 +172,42 @@ int main (int argc, char **argv)
HPDF_Font_SetCharacterEncoding (detail_font, HPDF_CHARENC_WCHAR_T);
- //detail_font_name = "MS-Mincho";
- //detail_font_v = HPDF_GetFont (pdf, detail_font_name, "UniJIS-UTF16-V");
-
- //relief_font = detail_font_v;
+ //detail_font_name = HPDF_LoadTTFontFromFile2 (pdf,
+ // "C:\\Windows\\Fonts\\batang.ttc", 1, ttopt);
detail_font_name = "Batang";
+ relief_font = detail_font_v;
detail_font_v = HPDF_GetFont (pdf, detail_font_name, "UniKS-UTF16-V");
- //HPDF_Font_SetReliefFont (detail_font_v, relief_font);
+ HPDF_Font_SetReliefFont (detail_font_v, relief_font);
- relief_font = detail_font_v;
+ //detail_font_name = HPDF_LoadTTFontFromFile (pdf,
+ // "C:\\Windows\\Fonts\\simhei.ttf", ttopt);
detail_font_name = "SimHei";
+ relief_font = detail_font_v;
detail_font_v = HPDF_GetFont (pdf, detail_font_name, "UniGB-UTF16-V");
HPDF_Font_SetReliefFont (detail_font_v, relief_font);
- HPDF_Font_SetCharacterEncoding (detail_font_v, HPDF_CHARENC_WCHAR_T);
-
+ detail_font_name = HPDF_LoadTTFontFromFile (pdf,
+ "C:\\Windows\\Fonts\\arial.ttf", ttopt);
+ relief_font = detail_font_v;
+ detail_font_v = HPDF_GetFont (pdf, detail_font_name, "Ancient-UTF16-H");
+ HPDF_Font_SetReliefFont (detail_font_v, relief_font);
- detail_font_name = "MS-Mincho";
- detail_font_v2 = HPDF_GetFont (pdf, detail_font_name, "90ms-RKSJ-V");
+ HPDF_Font_PushBuiltInConverter (detail_font_v, "BiDi", NULL);
+ HPDF_Font_SetCharacterEncoding (detail_font_v, HPDF_CHARENC_WCHAR_T);
/* Add a new page object. */
page = HPDF_AddPage (pdf);
- page_height = 841.88976F;
page_width = 595.27559F;
+ page_height = 841.88976F;
HPDF_Page_SetWidth (page, page_width);
HPDF_Page_SetHeight (page, page_height);
- rect.left = 30;
+ rect.left = page_width / 2 - 10;
rect.bottom = page_height - 60;
- rect.right = 50;
+ rect.right = page_width / 2 + 10;
rect.top = page_height - 80;
HPDF_Page_CreateTextAnnot (page, rect, (const char *)HELLO,
HPDF_GetUTFEncoder (pdf, HPDF_CHARENC_WCHAR_T));
@@ -205,58 +215,45 @@ int main (int argc, char **argv)
HPDF_Page_BeginText (page);
HPDF_Page_SetFontAndSize (page, detail_font, 15);
-
- HPDF_Page_SetWordSpace (page, 10);
+ HPDF_Page_SetWordSpace (page, 5);
HPDF_Page_SetCharSpace (page, 0);
- HPDF_Page_MoveTextPos (page, 30, page_height - 40);
- HPDF_Page_ShowText (page, (const char *)HELLO);
+ HPDF_Page_TextOut (page, 20, page_height - 50, (const char *)HELLO);
+ HPDF_Page_ShowText (page, (const char *)HELLO_ru);
- HPDF_Page_SetWordSpace (page, 6);
- HPDF_Page_SetCharSpace (page, 0);
- HPDF_Page_SetJustifyRatio (page, 10, 0, 1000);
+ HPDF_Page_SetTextLeading (page, 0);
+ HPDF_Page_SetJustifyRatio (page, 1, 1, 100);
- HPDF_Page_TextRect (page, 30, page_height - 90,
+ HPDF_Page_TextRect (page, 30, page_height - 60,
page_width / 2 - 29, 30, (const char *)ONCE_UPON_A_TIME,
- HPDF_TALIGN_JUSTIFY | HPDF_TALIGNOPT_BIDI_EACH_PARAGRAPH | HPDF_TALIGNOPT_REMOVE_TATWEEL, &len);
+ HPDF_TALIGN_JUSTIFY | HPDF_VALIGN_JUSTIFY_ALL |
+ HPDF_ALIGNOPT_BIDI_EACH_PARAGRAPH | HPDF_ALIGNOPT_REMOVE_TATWEEL,
+ &len);
HPDF_Page_SetFontAndSize (page, detail_font_v, 15);
+ HPDF_Page_SetWordSpace (page, 0);
+
+ HPDF_Page_SetTextLeading (page, 30);
+ HPDF_Page_TextOut (page, page_width / 2 + 20, page_height - 90,
+ (const char *)HELLO_ru);
+ HPDF_Page_ShowText (page, (const char *)HELLO);
+ HPDF_Page_ShowTextNextLine (page, NULL);
+ HPDF_Page_ShowText (page, (const char *)HELLO_ru);
+ HPDF_Page_ShowText (page, (const char *)L"!!!!");
+
+ HPDF_Page_SetTextLeading (page, 0);
+
+ HPDF_Page_TextRect (page, page_width / 2 + 40, page_height - 60,
+ page_width - 30, 405, (const char *)ONCE_UPON_A_TIME,
+ HPDF_TALIGN_JUSTIFY | HPDF_VALIGN_JUSTIFY, &len);
+
+ HPDF_Page_SetTextLeading (page, -20);
- HPDF_Page_SetWordSpace (page, 4);
- HPDF_Page_SetCharSpace (page, -2);
- HPDF_Page_SetJustifyRatio (page, 1, 1, 0);
-
- HPDF_Page_TextRect (page, page_width / 2 + 30, page_height - 90,
- page_width - 30, 450, (const char *)ONCE_UPON_A_TIME,
- HPDF_TALIGN_JUSTIFY, &len);
-
- HPDF_Page_SetFontAndSize (page, detail_font_v2, 15);
-
- HPDF_Page_SetWordSpace (page, -1);
- HPDF_Page_SetCharSpace (page, 4);
- HPDF_Page_SetJustifyRatio (page, 2, 1, 0);
- HPDF_Page_SetTextLeading (page, -10);
-
- HPDF_Page_TextRect (page, page_width / 2 + 30, 400, page_width - 30, 30,
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. "
- "A quick brown fox jumps over the lazy dog. ",
- HPDF_TALIGN_JUSTIFY, &len);
+ HPDF_Page_TextRect (page, page_width / 2 + 40, 380, page_width - 30, 30,
+ (const char *)ONCE_UPON_A_TIME + len,
+ HPDF_TALIGN_JUSTIFY | HPDF_VALIGN_JUSTIFY |
+ HPDF_ALIGNOPT_BIDI_EACH_PARAGRAPH | HPDF_ALIGNOPT_REMOVE_TATWEEL,
+ &len);
/* Finish to print text. */
HPDF_Page_EndText (page);
@@ -268,16 +265,16 @@ int main (int argc, char **argv)
HPDF_Page_LineTo (page, page_width - 10, page_height - 25);
HPDF_Page_Stroke (page);
- HPDF_Page_Rectangle (page, 30, page_height - 90,
- page_width / 2 - 29 - 30, 30 - (page_height - 90));
+ HPDF_Page_Rectangle (page, 30, page_height - 60,
+ page_width / 2 - 29 - 30, 30 - (page_height - 60));
HPDF_Page_Stroke (page);
- HPDF_Page_Rectangle (page, page_width / 2 + 30, page_height - 90,
- page_width - 30 - (page_width / 2 + 30), 450 - (page_height - 90));
+ HPDF_Page_Rectangle (page, page_width / 2 + 40, page_height - 60,
+ page_width - 30 - (page_width / 2 + 40), 405 - (page_height - 60));
HPDF_Page_Stroke (page);
- HPDF_Page_Rectangle (page, page_width / 2 + 30, 400,
- page_width - 30 - (page_width / 2 + 30), 30 - 400);
+ HPDF_Page_Rectangle (page, page_width / 2 + 40, 380,
+ page_width - 30 - (page_width / 2 + 40), 30 - 380);
HPDF_Page_Stroke (page);
diff --git a/include/hpdf.h b/include/hpdf.h
index fd76c1e..8199a32 100644
--- a/include/hpdf.h
+++ b/include/hpdf.h
@@ -969,19 +969,16 @@ HPDF_Font_MeasureText (HPDF_Font font,
HPDF_EXPORT(HPDF_UINT)
-HPDF_Font_MeasureTextEx (HPDF_Font font,
- const char *text,
- HPDF_UINT len,
- HPDF_REAL width,
- HPDF_REAL font_size,
- HPDF_REAL char_space,
- HPDF_REAL word_space,
- HPDF_INT options,
- HPDF_REAL *real_width,
- HPDF_UINT *numbytes,
- HPDF_UINT *numchars,
- HPDF_UINT *numspaces,
- HPDF_UINT *numtatweels);
+HPDF_Font_MeasureTextLines (HPDF_Font font,
+ const char *text,
+ HPDF_UINT len,
+ HPDF_REAL line_width,
+ HPDF_REAL font_size,
+ HPDF_REAL char_space,
+ HPDF_REAL word_space,
+ HPDF_INT options,
+ HPDF_TextLineWidth *width,
+ HPDF_UINT max_lines);
HPDF_EXPORT(HPDF_STATUS)
@@ -1079,15 +1076,12 @@ HPDF_Page_MeasureText (HPDF_Page page,
HPDF_EXPORT(HPDF_UINT)
-HPDF_Page_MeasureTextEx (HPDF_Page page,
- const char *text,
- HPDF_REAL width,
- HPDF_INT options,
- HPDF_REAL *real_width,
- HPDF_UINT *numbytes,
- HPDF_UINT *numchars,
- HPDF_UINT *numspaces,
- HPDF_UINT *numtatweels);
+HPDF_Page_MeasureTextLines (HPDF_Page page,
+ const char *text,
+ HPDF_REAL line_width,
+ HPDF_INT options,
+ HPDF_TextLineWidth *width,
+ HPDF_UINT max_lines);
HPDF_EXPORT(HPDF_REAL)
@@ -1649,6 +1643,11 @@ HPDF_Page_SetJustifyRatio (HPDF_Page page,
HPDF_REAL kashida);
+HPDF_EXPORT(HPDF_STATUS)
+HPDF_Page_InterlinearAnnotationRatio (HPDF_Page page,
+ HPDF_REAL ratio);
+
+
HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetSlideShow (HPDF_Page page,
HPDF_TransitionStyle type,
diff --git a/include/hpdf_consts.h b/include/hpdf_consts.h
index b61d46c..98ac6fe 100644
--- a/include/hpdf_consts.h
+++ b/include/hpdf_consts.h
@@ -550,22 +550,31 @@
/*----- Font options ---------------------------------------------------------*/
#define HPDF_FONTOPT_EMBEDDING 0x00000001
-#define HPDF_FONTOPT_WITH_CID_MAP 0x00000002
+#define HPDF_FONTOPT_WITHOUT_CID_MAP 0x00000002
#define HPDF_FONTOPT_WITHOUT_TOUNICODE_MAP 0x00000004
/*----------------------------------------------------------------------------*/
/*----- MeasureText options --------------------------------------------------*/
-#define HPDF_MEASURE_WORD_WRAP 0x00000001
-#define HPDF_MEASURE_CAN_SHORTEN 0x00000002
-#define HPDF_MEASURE_IGNORE_TATWEEL 0x00000004
+#define HPDF_MEASURE_WORD_WRAP 0x00000001
+#define HPDF_MEASURE_CAN_SHORTEN 0x00000002
+#define HPDF_MEASURE_IGNORE_TATWEEL 0x00000004
+
+/*----- TextLineWidth flags --------------------------------------------------*/
+
+#define HPDF_TLW_WORD_WRAP 0x0001
+#define HPDF_TLW_SHORTEN 0x0002
+#define HPDF_TLW_IGNORE_TATWEEL 0x0004
+#define HPDF_TLW_HYPHENATION 0x0100
+#define HPDF_TLW_PRAGRAPH_BREAK 0x0200
+#define HPDF_TLW_PAGE_BREAK 0x0400
/*----------------------------------------------------------------------------*/
-/*----- Convert flag ---------------------------------------------------------*/
+/*----- Convert flags --------------------------------------------------------*/
-#define HPDF_CONVERT_HOLD_CHARACTERS 0x00000001
+#define HPDF_CONVERT_HOLD_CHARACTERS 0x00000001
/*----------------------------------------------------------------------------*/
diff --git a/include/hpdf_font.h b/include/hpdf_font.h
index 5edc6a3..33f5519 100644
--- a/include/hpdf_font.h
+++ b/include/hpdf_font.h
@@ -104,6 +104,13 @@ HPDF_Type0Font_New (HPDF_MMgr mmgr,
HPDF_Xref xref);
+HPDF_TextWidth
+HPDF_Font_TextCacheWidth (HPDF_Font font,
+ HPDF_BOOL ignore_flags,
+ HPDF_UINT cache_begin,
+ HPDF_UINT cache_end);
+
+
HPDF_BOOL
HPDF_Font_Validate (HPDF_Font font);
@@ -147,6 +154,13 @@ HPDF_Font_GetReliefFont (HPDF_Font font,
HPDF_BYTE *index);
+#define HPDF_RELIEF_FONT_INDEX_MASK 0x0F
+#define HPDF_INTERLINEAR_ANNOTATED 0x80
+#define HPDF_INTERLINEAR_ANNOTATION 0x40
+/* reserved for TATECHUYOKO 0x20 */
+/* reserved 0x10 */
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/include/hpdf_gstate.h b/include/hpdf_gstate.h
index 3f2a3bb..4cb3b90 100644
--- a/include/hpdf_gstate.h
+++ b/include/hpdf_gstate.h
@@ -60,8 +60,10 @@ typedef struct _HPDF_GState_Rec {
HPDF_REAL gray_stroke;
HPDF_Font font;
- HPDF_REAL font_size;
HPDF_Font actual_font;
+ HPDF_REAL font_size;
+ HPDF_REAL actual_font_size;
+ HPDF_REAL ia_font_size_ratio;
HPDF_WritingMode writing_mode;
HPDF_GState prev;
diff --git a/include/hpdf_pages.h b/include/hpdf_pages.h
index 44b816c..6e4dd66 100644
--- a/include/hpdf_pages.h
+++ b/include/hpdf_pages.h
@@ -60,12 +60,13 @@ typedef struct _HPDF_PageAttr_Rec {
HPDF_Point cur_pos;
HPDF_Point text_pos;
HPDF_TransMatrix text_matrix;
+ HPDF_BOOL fake_text_pos;
HPDF_UINT16 gmode;
HPDF_Dict contents;
HPDF_Stream stream;
HPDF_Xref xref;
HPDF_UINT compression_mode;
- HPDF_PDFVer *ver;
+ HPDF_PDFVer *ver;
} HPDF_PageAttr_Rec;
diff --git a/include/hpdf_types.h b/include/hpdf_types.h
index 422b60d..a54810c 100644
--- a/include/hpdf_types.h
+++ b/include/hpdf_types.h
@@ -209,6 +209,18 @@ typedef struct _HPDF_TextWidth {
} HPDF_TextWidth;
+typedef struct _HPDF_TextLineWidth {
+ HPDF_UINT16 flags;
+ HPDF_UINT16 linebytes;
+ HPDF_UINT16 numbytes;
+ HPDF_UINT16 numchars;
+ HPDF_UINT16 numspaces;
+ HPDF_UINT16 numtatweels;
+ HPDF_UINT charswidth;
+ HPDF_REAL width;
+} HPDF_TextLineWidth;
+
+
/*---------------------------------------------------------------------------*/
/*------ dash mode ----------------------------------------------------------*/
@@ -307,6 +319,8 @@ typedef enum _HPDF_TextRenderingMode {
typedef enum _HPDF_WritingMode {
HPDF_WMODE_HORIZONTAL = 0,
HPDF_WMODE_VERTICAL,
+ HPDF_WMODE_SIDEWAYS, /* gstate only */
+ HPDF_WMODE_MIXED, /* gstate only */
HPDF_WMODE_EOF
} HPDF_WritingMode;
@@ -373,8 +387,8 @@ typedef enum _HPDF_AnnotType {
HPDF_ANNOT_POPUP,
HPDF_ANNOT_3D,
HPDF_ANNOT_SQUIGGLY,
- HPDF_ANNOT_LINE,
- HPDF_ANNOT_PROJECTION
+ HPDF_ANNOT_LINE,
+ HPDF_ANNOT_PROJECTION
} HPDF_AnnotType;
@@ -551,15 +565,24 @@ typedef enum _HPDF_ByteType {
typedef enum _HPDF_TextAlignment {
- HPDF_TALIGN_LEFT = 0,
- HPDF_TALIGN_RIGHT,
- HPDF_TALIGN_CENTER,
- HPDF_TALIGN_JUSTIFY,
- HPDF_TALIGN_JUSTIFY_ALL,
- HPDF_TALIGN_STRETCH,
- HPDF_TALIGN_MASK = 0x0000000F,
- HPDF_TALIGNOPT_BIDI_EACH_PARAGRAPH = 0x40000000,
- HPDF_TALIGNOPT_REMOVE_TATWEEL = 0x20000000,
+ HPDF_TALIGN_LEFT = 0,
+ HPDF_TALIGN_RIGHT = 1,
+ HPDF_TALIGN_CENTER = 2,
+ HPDF_TALIGN_JUSTIFY = 3,
+ HPDF_TALIGN_STRETCH = 4,
+ HPDF_TALIGN_JUSTIFY_ALL = 0x83,
+ HPDF_TALIGN_STRETCH_ALL = 0x84,
+ HPDF_TALIGN_MASK = 0xFF,
+ HPDF_VALIGN_TOP = 0x0000,
+ HPDF_VALIGN_BOTTOM = 0x0100,
+ HPDF_VALIGN_CENTER = 0x0200,
+ HPDF_VALIGN_JUSTIFY = 0x0300,
+ HPDF_VALIGN_STRETCH = 0x0400,
+ HPDF_VALIGN_JUSTIFY_ALL = 0x8300,
+ HPDF_VALIGN_STRETCH_ALL = 0x8400,
+ HPDF_VALIGN_MASK = 0xFF00,
+ HPDF_ALIGNOPT_BIDI_EACH_PARAGRAPH = 0x40000000,
+ HPDF_ALIGNOPT_REMOVE_TATWEEL = 0x20000000,
} HPDF_TextAlignment;
/*----------------------------------------------------------------------------*/
diff --git a/src/hpdf_encoder_utf.c b/src/hpdf_encoder_utf.c
index de57767..10ec6f2 100644
--- a/src/hpdf_encoder_utf.c
+++ b/src/hpdf_encoder_utf.c
@@ -438,7 +438,7 @@ Ancient_UTF16_H_Init (HPDF_Encoder encoder,
static const char MODERN_ENCODERS[][17] = {
"",
- "UTF-8", /* not "Modern-UTF8-H" for backward compatibility */
+ "Modern-UTF8-H",
"Modern-UTF16-H",
"Modern-UTF32-H",
"Modern-UCS2LE-H",
diff --git a/src/hpdf_font.c b/src/hpdf_font.c
index f5db87d..39bac6e 100644
--- a/src/hpdf_font.c
+++ b/src/hpdf_font.c
@@ -67,14 +67,14 @@ IsCIDText (HPDF_Font font,
static HPDF_UINT
-MeasureTextEx (HPDF_Font font,
- HPDF_REAL width,
- HPDF_REAL font_size,
- HPDF_REAL char_space,
- HPDF_REAL word_space,
- HPDF_INT options,
- HPDF_REAL *real_width,
- HPDF_UINT *numtatweels);
+MeasureTextCache (HPDF_Font font,
+ HPDF_REAL line_width,
+ HPDF_REAL font_size,
+ HPDF_REAL char_space,
+ HPDF_REAL word_space,
+ HPDF_INT options,
+ HPDF_UINT cache_begin,
+ HPDF_TextLineWidth *width);
static HPDF_BOOL
@@ -86,10 +86,10 @@ CanBreakBefore (HPDF_UCS4 b);
static HPDF_UINT
-GetUncovertedBytes (HPDF_Font font,
- const char *text,
- HPDF_UINT len,
- HPDF_UINT *numbytes);
+GetUncovertedBytes (HPDF_Font font,
+ const char *text,
+ HPDF_UINT cache_begin,
+ HPDF_TextLineWidth *width);
static HPDF_CharEnc
@@ -107,10 +107,6 @@ HPDF_Font_TextWidth (HPDF_Font font,
{
HPDF_TextWidth tw = {0, 0, 0, 0};
HPDF_FontAttr attr;
- HPDF_UINT i;
- HPDF_UCS4 b;
- HPDF_BYTE *pirf;
- HPDF_UINT bytes;
HPDF_PTRACE ((" HPDF_Font_TextWidth\n"));
@@ -137,38 +133,53 @@ HPDF_Font_TextWidth (HPDF_Font font,
return attr->tw_cache;
}
- text = attr->text_cache;
- pirf = attr->text_cache + (attr->text_cache_allocated / 2);
- len = attr->text_cache_len;
- b = 0;
- i = 0;
+ attr->tw_cache = HPDF_Font_TextCacheWidth (font, HPDF_FALSE,
+ 0, attr->text_cache_len);
+
+ return attr->tw_cache;
+}
+
+
+HPDF_TextWidth
+HPDF_Font_TextCacheWidth (HPDF_Font font,
+ HPDF_BOOL ignore_flags,
+ HPDF_UINT cache_begin,
+ HPDF_UINT cache_end)
+{
+ HPDF_TextWidth tw = {0, 0, 0, 0};
+ HPDF_FontAttr attr = (HPDF_FontAttr)font->attr;
+ const HPDF_BYTE *text = attr->text_cache;
+ HPDF_BYTE *pirf = attr->text_cache + (attr->text_cache_allocated / 2);
+ HPDF_BYTE irf;
+ HPDF_UCS4 b = 0;
+ HPDF_UINT i, bytes;
- while (i < len) {
+ HPDF_PTRACE ((" HPDF_Font_TextCacheWidth\n"));
+
+ for (i = cache_begin; i < cache_end; i += bytes) {
HPDF_UINT cw;
- cw = attr->char_width_fn (font, HPDF_TRUE, *pirf, text, &bytes, &b);
- tw.width += cw;
+ irf = pirf[i] & HPDF_RELIEF_FONT_INDEX_MASK;
+ cw = attr->char_width_fn (font, HPDF_TRUE, irf, text+i, &bytes, &b);
+
+ if (!ignore_flags && (pirf[i] & HPDF_INTERLINEAR_ANNOTATION))
+ continue;
+ tw.width += cw;
tw.numchars++;
- if (b == 0x20 && bytes == 1 && !IsCIDText (font, *pirf)) {
+ if (b == 0x20 && bytes == 1 && !IsCIDText (font, irf)) {
tw.numwords++;
tw.numspace++;
}
-
- pirf += bytes;
- text += bytes;
- i += bytes;
}
/* 2006.08.19 add. */
- if (b == 0x20 && bytes == 1 && !IsCIDText (font, *pirf))
+ if (b == 0x20 && bytes == 1 && !IsCIDText (font, irf))
; /* do nothing. */
else
tw.numwords++;
- attr->tw_cache = tw;
-
return tw;
}
@@ -184,36 +195,41 @@ HPDF_Font_MeasureText (HPDF_Font font,
HPDF_INT options,
HPDF_REAL *real_width)
{
+ HPDF_TextLineWidth tlw;
+ HPDF_UINT lines;
+
HPDF_PTRACE ((" HPDF_Font_MeasureText\n"));
- return HPDF_Font_MeasureTextEx (font, (const char *)text, len, width,
- font_size, char_space, word_space, options, real_width,
- NULL, NULL, NULL, NULL);
+ lines = HPDF_Font_MeasureTextLines (font, (const char *)text, len, width,
+ font_size, char_space, word_space, options, &tlw, 1);
+ if (!lines)
+ return 0;
+
+ if (real_width)
+ *real_width = tlw.width;
+ return tlw.linebytes;
}
HPDF_EXPORT(HPDF_UINT)
-HPDF_Font_MeasureTextEx (HPDF_Font font,
- const char *text,
- HPDF_UINT len,
- HPDF_REAL width,
- HPDF_REAL font_size,
- HPDF_REAL char_space,
- HPDF_REAL word_space,
- HPDF_INT options,
- HPDF_REAL *real_width,
- HPDF_UINT *numbytes,
- HPDF_UINT *numchars,
- HPDF_UINT *numspaces,
- HPDF_UINT *numtatweels)
+HPDF_Font_MeasureTextLines (HPDF_Font font,
+ const char *text,
+ HPDF_UINT len,
+ HPDF_REAL line_width,
+ HPDF_REAL font_size,
+ HPDF_REAL char_space,
+ HPDF_REAL word_space,
+ HPDF_INT options,
+ HPDF_TextLineWidth *width,
+ HPDF_UINT max_lines)
{
HPDF_FontAttr attr;
- HPDF_UINT cvt_len, tmp_len, tatweels;
- HPDF_REAL rw, margin;
+ HPDF_UINT line, begin, cvt_len;
+ HPDF_REAL margin;
- HPDF_PTRACE ((" HPDF_Font_MeasureTextEx\n"));
+ HPDF_PTRACE ((" HPDF_Font_MeasureTextLines\n"));
- if (!HPDF_Font_Validate(font) || !text)
+ if (!HPDF_Font_Validate(font) || !text || !width)
return 0;
if (len > HPDF_LIMIT_MAX_STRING_LEN) {
@@ -228,54 +244,60 @@ HPDF_Font_MeasureTextEx (HPDF_Font font,
return 0;
}
- if (!real_width)
- real_width = &rw;
- if (!numtatweels)
- numtatweels = &tatweels;
-
margin = 1.25F; /* margin 25% */
do { /* estimate result length and convert only the length+margin */
+ HPDF_UINT cache_begin, cache_end;
+ HPDF_REAL w = 0;
+
if (!attr->width_per_byte) /* expect average width is missing_width/2 */
attr->width_per_byte = (HPDF_REAL)attr->fontdef->missing_width / 2 /
MINBYTES[GetSourceCharEnc (font)];
- cvt_len = (HPDF_UINT)(width / font_size * 1000 / attr->width_per_byte
- * margin);
+ cvt_len = (HPDF_UINT)(line_width * max_lines / font_size * 1000 *
+ margin / attr->width_per_byte);
if (len < cvt_len)
cvt_len = len;
if (HPDF_Font_ConvertText (font, HPDF_CONVERT_HOLD_CHARACTERS,
text, cvt_len) != HPDF_OK)
return 0;
-
- tmp_len = MeasureTextEx (font, width, font_size, char_space, word_space,
- options, real_width, numtatweels);
-
- if (numchars)
- *numchars = attr->tw_cache.numchars;
- if (numspaces)
- *numspaces = attr->tw_cache.numspace;
-
- tmp_len = GetUncovertedBytes (font, text, tmp_len, numbytes);
-
- if (8 < tmp_len) /* ignore too short sample */
- attr->width_per_byte = *real_width / font_size * 1000 / tmp_len;
+
+ for (begin = 0, cache_begin = 0, line = 0;
+ line < max_lines &&
+ begin < cvt_len &&
+ !(line && (width[line - 1].flags & HPDF_TLW_PAGE_BREAK));
+ line++) {
+ MeasureTextCache (font, line_width, font_size, char_space,
+ word_space, options, cache_begin, width + line);
+ w += width[line].width;
+ if (line_width < width[line].width)
+ width[line].flags |= HPDF_TLW_SHORTEN;
+
+ cache_end = cache_begin + width[line].linebytes;
+ GetUncovertedBytes (font, text + begin, cache_begin, width + line);
+
+ begin += width[line].linebytes;
+ cache_begin = cache_end;
+ }
+
+ if (8 < begin) /* ignore too short sample */
+ attr->width_per_byte = w / font_size * 1000 / begin;
margin += 0.25F; /* margin +25% */
- } while (cvt_len <= tmp_len + 4 && cvt_len < len); /* while misestimate */
+ } while (cvt_len <= begin + 4 && cvt_len < len); /* while misestimate */
- return tmp_len;
+ return line;
}
static HPDF_UINT
-MeasureTextEx (HPDF_Font font,
- HPDF_REAL width,
- HPDF_REAL font_size,
- HPDF_REAL char_space,
- HPDF_REAL word_space,
- HPDF_INT options,
- HPDF_REAL *real_width,
- HPDF_UINT *numtatweels)
+MeasureTextCache (HPDF_Font font,
+ HPDF_REAL line_width,
+ HPDF_REAL font_size,
+ HPDF_REAL char_space,
+ HPDF_REAL word_space,
+ HPDF_INT options,
+ HPDF_UINT cache_begin,
+ HPDF_TextLineWidth *width)
{
HPDF_FontAttr attr;
HPDF_REAL w;
@@ -293,39 +315,46 @@ MeasureTextEx (HPDF_Font font,
attr = (HPDF_FontAttr)font->attr;
- text = attr->text_cache;
- pirf = attr->text_cache + (attr->text_cache_allocated / 2);
- len = attr->text_cache_len;
- attr->text_cache_len = 0;
- HPDF_MemSet (&attr->tw_cache, 0, sizeof attr->tw_cache);
- *real_width = 0;
+ text = attr->text_cache + cache_begin;
+ pirf = attr->text_cache + cache_begin + (attr->text_cache_allocated / 2);
+ len = attr->text_cache_len - cache_begin;
+ HPDF_MemSet (width, 0, sizeof *width);
tmp_len = 0;
nch = nsp = ntt = 0;
tw = 0;
w = v = 0;
for (i = 0; i < len; i += bytes) {
- HPDF_UCS4 b;
HPDF_REAL tmp_w;
+ HPDF_UCS4 b;
+ HPDF_BYTE irf;
HPDF_INT cw;
- cw = attr->char_width_fn (font, HPDF_TRUE, pirf[i], text + i, &bytes, &b);
-
- if (HPDF_IS_WHITE_SPACE(b)) {
- tmp_len = i + bytes;
- attr->text_cache_len = i;
- *real_width = w;
- attr->tw_cache.width = tw;
- attr->tw_cache.numchars = nch;
- attr->tw_cache.numspace = attr->tw_cache.numwords = nsp;
- *numtatweels = ntt;
+ irf = pirf[i] & HPDF_RELIEF_FONT_INDEX_MASK;
+ cw = attr->char_width_fn (font, HPDF_TRUE, irf, text+i, &bytes, &b);
- if (width < w || b == 0x0A || b == 0x0C || b == 0x0D)
- return tmp_len;
+ if (pirf[i] & HPDF_INTERLINEAR_ANNOTATION)
+ continue;
- if (b != 0x20) {
+ if (HPDF_IS_WHITE_SPACE(b) || b == 0x200B /* ZWSP */) {
+ width->linebytes = i + bytes;
+ width->numbytes = i;
+ width->numchars = nch;
+ width->numspaces = nsp;
+ width->numtatweels = ntt;
+ width->charswidth = tw;
+ width->width = w;
+
+ if (b == 0x0A || b == 0x0D)
+ return (width->flags |= HPDF_TLW_PRAGRAPH_BREAK);
+ if (b == 0x0C)
+ return (width->flags |= HPDF_TLW_PAGE_BREAK);
+ if (line_width < w)
+ return (width->flags |= HPDF_TLW_WORD_WRAP);
+
+ if (b != 0x20) { /* TAB, ZWSP */
continue;
- } else if (bytes == 1 && !IsCIDText (font, pirf[i])) {
+ } else if (bytes == 1 && !IsCIDText (font, irf)) {
nsp++;
w += word_space;
}
@@ -341,35 +370,23 @@ MeasureTextEx (HPDF_Font font,
hyphen_w += char_space;
}
tmp_w = hyphen_w;
- if (width < v + tmp_w ||
+ if (line_width < v + tmp_w ||
(!(options & HPDF_MEASURE_CAN_SHORTEN) &&
- width < w + tmp_w))
- return tmp_len;
+ line_width < w + tmp_w))
+ return (width->flags |= HPDF_TLW_WORD_WRAP);
}
- tmp_len = i + bytes;
- attr->text_cache_len = i + bytes;
- *real_width = w + tmp_w;
- attr->tw_cache.width = tw + cw;
- attr->tw_cache.numchars = nch;
- attr->tw_cache.numspace = attr->tw_cache.numwords = nsp;
- *numtatweels = ntt;
-
- if (width < w + tmp_w)
- return tmp_len;
+ width->linebytes = i + bytes;
+ width->numbytes = i + bytes;
+ width->numchars = nch;
+ width->numspaces = nsp;
+ width->numtatweels = ntt;
+ width->charswidth = tw + cw;
+ width->width = w + tmp_w;
- continue;
- } else if (b == 0x200B) { /* ZWSP */
- tmp_len = i + bytes;
- attr->text_cache_len = i;
- *real_width = w;
- attr->tw_cache.width = tw;
- attr->tw_cache.numchars = nch;
- attr->tw_cache.numspace = attr->tw_cache.numwords = nsp;
- *numtatweels = ntt;
-
- if (width < w)
- return tmp_len;
+ if (line_width < w + tmp_w)
+ return (width->flags |=
+ (HPDF_TLW_WORD_WRAP | HPDF_TLW_HYPHENATION));
continue;
} else if ((b <= 0x001F) ||
@@ -381,59 +398,62 @@ MeasureTextEx (HPDF_Font font,
(0xFFF0 <= b && b <= 0xFFFF)) { /* control codes */
continue;
} else if (!(options & HPDF_MEASURE_WORD_WRAP) ||
- (can_break && CanBreakBefore (b))) {
- tmp_len = i;
- attr->text_cache_len = i;
- *real_width = w;
- attr->tw_cache.width = tw;
- attr->tw_cache.numchars = nch;
- attr->tw_cache.numspace = attr->tw_cache.numwords = nsp;
- *numtatweels = ntt;
-
- if (width < w)
- return tmp_len;
+ (!(pirf[i] & HPDF_INTERLINEAR_ANNOTATED) &&
+ can_break && CanBreakBefore (b))) {
+ width->linebytes = i;
+ width->numbytes = i;
+ width->numchars = nch;
+ width->numspaces = nsp;
+ width->numtatweels = ntt;
+ width->charswidth = tw;
+ width->width = w;
+
+ if (line_width < w)
+ return width->flags;
}
if ((options & HPDF_MEASURE_WORD_WRAP) &&
- (attr->type == HPDF_FONT_TYPE0_CID ||
- attr->type == HPDF_FONT_TYPE0_TT))
+ (attr->type == HPDF_FONT_TYPE0_CID ||
+ attr->type == HPDF_FONT_TYPE0_TT))
can_break = CanBreakAfter (b);
- nch++;
-
- tw += cw;
tmp_w = (HPDF_REAL)cw * font_size / 1000;
if (b == 0x0640) { /* Arabic tatweel */
ntt++;
- if (!(options & HPDF_MEASURE_IGNORE_TATWEEL)) {
+ if (options & HPDF_MEASURE_IGNORE_TATWEEL) {
+ width->flags |= HPDF_TLW_IGNORE_TATWEEL;
+ } else {
+ nch++;
+ tw += cw;
w += tmp_w;
if (0 < i)
w += char_space;
}
} else {
+ nch++;
+ tw += cw;
w += tmp_w;
v += tmp_w;
- if (0 < i) {
+ if (0 < i)
w += char_space;
- v += char_space;
- }
}
- if (width < v || (!(options & HPDF_MEASURE_CAN_SHORTEN) && width < w))
- return tmp_len;
+ if (line_width < v ||
+ (!(options & HPDF_MEASURE_CAN_SHORTEN) && line_width < w))
+ return (width->flags |= HPDF_TLW_WORD_WRAP);
}
/* all of text can be put in the specified width */
- tmp_len = i;
- attr->text_cache_len = i;
- *real_width = w;
- attr->tw_cache.width = tw;
- attr->tw_cache.numchars = nch;
- attr->tw_cache.numspace = attr->tw_cache.numwords = nsp;
- *numtatweels = ntt;
-
- return tmp_len;
+ width->linebytes = i;
+ width->numbytes = i;
+ width->numchars = nch;
+ width->numspaces = nsp;
+ width->numtatweels = ntt;
+ width->charswidth = tw;
+ width->width = w;
+
+ return width->flags;
}
@@ -747,7 +767,7 @@ BiDi_FreeArrays (HPDF_ConverterBiDi bidi)
}
-static HPDF_UINT HPDF_STDCALL
+static HPDF_UINT HPDF_STDCALL
BiDi (HPDF_Converter converter,
HPDF_UINT32 flags,
const HPDF_BYTE *src,
@@ -915,7 +935,7 @@ BiDi_New (HPDF_Alloc_Func alloc_fn,
#endif /* LIBHPDF_ENABLE_BIDI */
-static HPDF_UINT HPDF_STDCALL
+static HPDF_UINT HPDF_STDCALL
EncConv (HPDF_Converter converter,
HPDF_UINT32 flags,
const HPDF_BYTE *src,
@@ -946,7 +966,7 @@ EncConv (HPDF_Converter converter,
}
-static HPDF_UINT HPDF_STDCALL
+static HPDF_UINT HPDF_STDCALL
Swap16 (HPDF_Converter converter,
HPDF_UINT32 flags,
const HPDF_BYTE *src,
@@ -967,7 +987,7 @@ Swap16 (HPDF_Converter converter,
}
-static HPDF_UINT HPDF_STDCALL
+static HPDF_UINT HPDF_STDCALL
Swap32 (HPDF_Converter converter,
HPDF_UINT32 flags,
const HPDF_BYTE *src,
@@ -1239,6 +1259,9 @@ HPDF_Font_ConvertText (HPDF_Font font,
if (!text)
return HPDF_OK;
+ if (!len)
+ len = HPDF_Font_StrLen(font, text, HPDF_LIMIT_MAX_STRING_LEN + 1);
+
if (!attr->text_cache)
HPDF_NormalizeCharEnc (&attr->encoder->charenc);
@@ -1276,6 +1299,7 @@ HPDF_Font_ConvertText (HPDF_Font font,
return HPDF_CheckError (font->error);
}
+ /* do convert */
if (!list || list->count <= 0) {
HPDF_MemCpy (attr->text_cache, text, attr->text_cache_len);
text = (char *)(dst = attr->text_cache);
@@ -1291,13 +1315,21 @@ HPDF_Font_ConvertText (HPDF_Font font,
}
}
+ /* set relief font index */
+ if (attr->relief_font)
+ SetReliefFontIndex (font);
+
+ /* remove control character */
if (!(flags & HPDF_CONVERT_HOLD_CHARACTERS)) {
HPDF_UINT bytes;
HPDF_UCS4 b = 0;
+ HPDF_UINT irfofs = attr->text_cache_allocated / 2;
for (i = 0; i < attr->text_cache_len;) {
b = HPDF_Encoder_GetUcs4 (attr->encoder, (const HPDF_BYTE *)text,
&bytes);
+ if (!bytes)
+ bytes = 1;
i += bytes;
if ((b <= 0x001F) ||
(0x007F <= b && b <= 0x009F) ||
@@ -1309,63 +1341,59 @@ HPDF_Font_ConvertText (HPDF_Font font,
(0xFFF0 <= b && b <= 0xFFFF)) /* control codes */
text += bytes;
else
- while (bytes--)
+ while (bytes--) {
+ dst[irfofs] = ((const HPDF_BYTE *)text)[irfofs];
*dst++ = *(const HPDF_BYTE *)text++;
+ }
}
if (b == 0x00AD) {
+ HPDF_BYTE irf;
+ HPDF_Font_GetReliefFont (font, '-', &irf);
+ bytes = 1;
if (attr->encoder->charenc == HPDF_CHARENC_UNSUPPORTED ||
attr->encoder->charenc == HPDF_CHARENC_UTF8)
- *dst++ = '-';
+ *dst = '-';
else
- dst += UCS4TO_FNS[attr->encoder->charenc] (dst, '-');
+ bytes = UCS4TO_FNS[attr->encoder->charenc] (dst, '-');
+ while (bytes--)
+ (dst++)[irfofs] = irf;
}
attr->text_cache_len = (HPDF_UINT)(dst - attr->text_cache);
}
- /* set relief font index */
- HPDF_MemSet (attr->text_cache + (attr->text_cache_allocated / 2),
- 0, attr->text_cache_allocated / 2);
- if (attr->relief_font)
- SetReliefFontIndex (font);
-
return HPDF_OK;
}
static HPDF_UINT
-GetUncovertedBytes (HPDF_Font font,
- const char *text,
- HPDF_UINT len,
- HPDF_UINT *numbytes)
+GetUncovertedBytes (HPDF_Font font,
+ const char *text,
+ HPDF_UINT cache_begin,
+ HPDF_TextLineWidth *width)
{
HPDF_FontAttr attr;
HPDF_CharEnc src_charenc;
HPDF_CharEnc dst_charenc;
- HPDF_UINT i, j, tmp_len;
+ HPDF_UINT i, j, numbytes;
attr = (HPDF_FontAttr)font->attr;
dst_charenc = attr->encoder->charenc;
- if (dst_charenc == HPDF_CHARENC_UNSUPPORTED) {
- if (numbytes)
- *numbytes = attr->text_cache_len;
- return len;
- }
+ if (dst_charenc == HPDF_CHARENC_UNSUPPORTED)
+ return width->linebytes;
src_charenc = GetSourceCharEnc (font);
- i = 0;
- j = 0;
- tmp_len = 0;
- while (i < len) {
- i += BYTES_FNS[dst_charenc] (attr->text_cache + i);
+ i = j = numbytes = 0;
+ while (i < width->linebytes) {
+ i += BYTES_FNS[dst_charenc] (attr->text_cache + cache_begin + i);
j += BYTES_FNS[src_charenc] ((const HPDF_BYTE *)text + j);
- if (attr->text_cache_len == i)
- tmp_len = j;
+ if (width->numbytes == i)
+ numbytes = j;
}
- if (numbytes)
- *numbytes = tmp_len;
+ width->numbytes = numbytes;
+ width->linebytes = j;
return j;
}
@@ -1589,8 +1617,7 @@ HPDF_Font_SetReliefFont (HPDF_Font font,
if (rf_attr->encoder != attr->encoder &&
(rf_attr->encoder->charenc == HPDF_CHARENC_UNSUPPORTED ||
- rf_attr->encoder->charenc != attr->encoder->charenc ||
- rf_attr->writing_mode != attr->writing_mode))
+ rf_attr->encoder->charenc != attr->encoder->charenc))
return HPDF_RaiseError (font->error,
HPDF_UNMATCHED_RELIEF_FONT, 0);
@@ -1616,7 +1643,8 @@ HPDF_Font_GetReliefFont (HPDF_Font font,
HPDF_FontAttr rfattr = (HPDF_FontAttr)rf->attr;
if (rfattr->fontdef->type != HPDF_FONT_TYPE1) {
- for (; rf; rf = rfattr->relief_font, irf++) {
+ for (; rf && irf <= HPDF_RELIEF_FONT_INDEX_MASK;
+ rf = rfattr->relief_font, irf++) {
rfattr = (HPDF_FontAttr)rf->attr;
if (rfattr->fontdef->type == HPDF_FONTDEF_TYPE_CID) {
/* cid-based font */
@@ -1634,8 +1662,11 @@ HPDF_Font_GetReliefFont (HPDF_Font font,
}
}
- if (rf && index)
- *index = irf;
+ if (HPDF_RELIEF_FONT_INDEX_MASK < irf)
+ rf = NULL;
+
+ if (index)
+ *index = (rf? irf: 0);
return rf;
}
@@ -1647,6 +1678,7 @@ SetReliefFontIndex (HPDF_Font font)
HPDF_FontAttr attr = (HPDF_FontAttr)font->attr;
HPDF_Encoder encoder = attr->encoder;
HPDF_BYTE irf = 0;
+ HPDF_BYTE irff = 0;
HPDF_ParseText_Rec parse_state;
HPDF_UINT i;
HPDF_BYTE *pirf = attr->text_cache + (attr->text_cache_allocated / 2);
@@ -1665,10 +1697,26 @@ SetReliefFontIndex (HPDF_Font font)
HPDF_UCS4 b = HPDF_Encoder_ToUcs4 (encoder,
attr->text_cache + i, bytes);
- if (!HPDF_Font_GetReliefFont (font, b, &irf))
- irf = 0xFF;
+ HPDF_Font_GetReliefFont (font, b, &irf);
+
+ switch (b) {
+ case 0xFFF9: /* IAA */
+ irff &= ~(HPDF_INTERLINEAR_ANNOTATED |
+ HPDF_INTERLINEAR_ANNOTATION);
+ irff |= HPDF_INTERLINEAR_ANNOTATED;
+ break;
+ case 0xFFFA: /* IAS */
+ irff &= ~(HPDF_INTERLINEAR_ANNOTATED |
+ HPDF_INTERLINEAR_ANNOTATION);
+ irff |= HPDF_INTERLINEAR_ANNOTATION;
+ break;
+ case 0xFFFB: /* IAT */
+ irff &= ~(HPDF_INTERLINEAR_ANNOTATED |
+ HPDF_INTERLINEAR_ANNOTATION);
+ break;
+ }
}
- pirf[i] = irf;
+ pirf[i] = irff | irf;
}
}
@@ -1679,14 +1727,13 @@ IsCIDText (HPDF_Font font,
{
HPDF_FontAttr rfattr = (HPDF_FontAttr)font->attr;
- if (index != 0xFF)
- while (index-- && rfattr) {
- if (!(font = rfattr->relief_font))
- break;
- rfattr = (HPDF_FontAttr)font->attr;
- }
+ while (index-- && rfattr) {
+ if (!(font = rfattr->relief_font))
+ break;
+ rfattr = (HPDF_FontAttr)font->attr;
+ }
return (rfattr->type == HPDF_FONT_TYPE0_TT &&
- !(((HPDF_TTFontDefAttr)rfattr->fontdef->attr)->options &
- HPDF_FONTOPT_WITH_CID_MAP));
+ (((HPDF_TTFontDefAttr)rfattr->fontdef->attr)->options &
+ HPDF_FONTOPT_WITHOUT_CID_MAP));
}
diff --git a/src/hpdf_font_cid.c b/src/hpdf_font_cid.c
index da3b402..9ff2cc2 100644
--- a/src/hpdf_font_cid.c
+++ b/src/hpdf_font_cid.c
@@ -134,7 +134,7 @@ HPDF_Type0Font_New (HPDF_MMgr mmgr,
ret += HPDF_Dict_AddName (font, "Encoding", encoder->name);
} else {
ttfontdef_attr = (HPDF_TTFontDefAttr)fontdef->attr;
- if (!(ttfontdef_attr->options & HPDF_FONTOPT_WITH_CID_MAP)) {
+ if (ttfontdef_attr->options & HPDF_FONTOPT_WITHOUT_CID_MAP) {
ret += HPDF_Dict_AddName (font, "Encoding",
((attr->writing_mode == HPDF_WMODE_HORIZONTAL)?
"Identity-H": "Identity-V"));
@@ -151,7 +151,7 @@ HPDF_Type0Font_New (HPDF_MMgr mmgr,
if (ttfontdef_attr &&
!(ttfontdef_attr->options & HPDF_FONTOPT_WITHOUT_TOUNICODE_MAP)) {
- if (!(ttfontdef_attr->options & HPDF_FONTOPT_WITH_CID_MAP))
+ if (ttfontdef_attr->options & HPDF_FONTOPT_WITHOUT_CID_MAP)
attr->to_unicode_stream =
CreateCMap (encoder, xref, HPDF_CMapType_CidToUnicode);
else
@@ -388,7 +388,7 @@ CIDFontType2_New (HPDF_Font parent, HPDF_Xref xref)
if (HPDF_Dict_Add (font, "DW2", array) != HPDF_OK)
return NULL;
- ret += HPDF_Array_AddNumber (array, (HPDF_INT32)(fontdef->font_bbox.bottom));
+ ret += HPDF_Array_AddNumber (array, (HPDF_INT32)(fontdef->font_bbox.top));
ret += HPDF_Array_AddNumber (array, (HPDF_INT32)(fontdef->font_bbox.bottom -
fontdef->font_bbox.top));
@@ -548,6 +548,7 @@ CIDFontType2_BeforeWrite_Func (HPDF_Dict obj)
ret += HPDF_Dict_AddName (descriptor, "Type", "FontDescriptor");
ret += HPDF_Dict_AddNumber (descriptor, "Ascent", def->ascent);
ret += HPDF_Dict_AddNumber (descriptor, "Descent", def->descent);
+ ret += HPDF_Dict_AddNumber (descriptor, "CapHeight", def->cap_height);
ret += HPDF_Dict_AddNumber (descriptor, "Flags", def->flags);
array = HPDF_Box_Array_New (obj->mmgr, def->font_bbox);
@@ -592,11 +593,8 @@ CharWidth (HPDF_Font font,
if (converted) {
code = HPDF_Encoder_GetUcs4 (attr->encoder, text, bytes);
- if (irf != 0xFF)
- while (irf-- && font)
- font = ((HPDF_FontAttr)font->attr)->relief_font;
- else
- font = NULL;
+ while (irf-- && font)
+ font = ((HPDF_FontAttr)font->attr)->relief_font;
} else {
code = HPDF_Font_GetUcs4 (font, (const char *)text, bytes);
font = HPDF_Font_GetReliefFont (font, code, NULL);
diff --git a/src/hpdf_font_tt.c b/src/hpdf_font_tt.c
index c2ae0b4..797bd41 100644
--- a/src/hpdf_font_tt.c
+++ b/src/hpdf_font_tt.c
@@ -240,11 +240,8 @@ CharWidth (HPDF_Font font,
*bytes = 1;
if (converted) {
- if (irf != 0xFF)
- while (irf-- && font)
- font = ((HPDF_FontAttr)font->attr)->relief_font;
- else
- font = NULL;
+ while (irf-- && font)
+ font = ((HPDF_FontAttr)font->attr)->relief_font;
} else {
font = HPDF_Font_GetReliefFont (font, *ucs4, NULL);
}
diff --git a/src/hpdf_font_type1.c b/src/hpdf_font_type1.c
index 606ea8b..c5b6dae 100644
--- a/src/hpdf_font_type1.c
+++ b/src/hpdf_font_type1.c
@@ -164,6 +164,7 @@ Type1Font_CreateDescriptor (HPDF_MMgr mmgr,
ret += HPDF_Dict_AddName (descriptor, "Type", "FontDescriptor");
ret += HPDF_Dict_AddNumber (descriptor, "Ascent", def->ascent);
ret += HPDF_Dict_AddNumber (descriptor, "Descent", def->descent);
+ ret += HPDF_Dict_AddNumber (descriptor, "CapHeight", def->cap_height);
ret += HPDF_Dict_AddNumber (descriptor, "Flags", def->flags);
array = HPDF_Box_Array_New (mmgr, def->font_bbox);
diff --git a/src/hpdf_gstate.c b/src/hpdf_gstate.c
index 4e758ba..fec051d 100644
--- a/src/hpdf_gstate.c
+++ b/src/hpdf_gstate.c
@@ -65,8 +65,10 @@ HPDF_GState_New (HPDF_MMgr mmgr,
gstate->gray_stroke = current->gray_stroke;
gstate->font = current->font;
- gstate->font_size = current->font_size;
gstate->actual_font = current->actual_font;
+ gstate->font_size = current->font_size;
+ gstate->actual_font_size = current->actual_font_size;
+ gstate->ia_font_size_ratio = current->ia_font_size_ratio;
gstate->writing_mode = current->writing_mode;
gstate->prev = current;
@@ -106,8 +108,10 @@ HPDF_GState_New (HPDF_MMgr mmgr,
gstate->gray_stroke = 0;
gstate->font = NULL;
- gstate->font_size = 0;
gstate->actual_font = NULL;
+ gstate->font_size = 0;
+ gstate->actual_font_size = 0;
+ gstate->ia_font_size_ratio = 0.5F;
gstate->writing_mode = HPDF_WMODE_HORIZONTAL;
gstate->prev = NULL;
diff --git a/src/hpdf_page_operator.c b/src/hpdf_page_operator.c
index b366879..e900b82 100644
--- a/src/hpdf_page_operator.c
+++ b/src/hpdf_page_operator.c
@@ -25,11 +25,37 @@ static const HPDF_DashMode INIT_MODE = {{0, 0, 0, 0, 0, 0, 0, 0}, 0, 0};
static HPDF_STATUS
-InternalWriteText (HPDF_Page page,
- HPDF_REAL tw,
- const char *prefix,
- const char *operator);
+SetCharSpace (HPDF_Page page,
+ HPDF_REAL value);
+static HPDF_STATUS
+SetWordSpace (HPDF_Page page,
+ HPDF_REAL value);
+
+static HPDF_STATUS
+SetFontAndSize (HPDF_Page page,
+ HPDF_Font font,
+ HPDF_BYTE flags,
+ HPDF_BOOL set_word_char_space,
+ HPDF_BOOL move_to_text_pos);
+
+static HPDF_Font
+GetActualFont (HPDF_Page page,
+ HPDF_UINT index);
+
+static HPDF_STATUS
+SetTextRise (HPDF_Page page);
+
+static HPDF_STATUS
+SetTextMatrix (HPDF_Page page);
+
+static HPDF_TransMatrix
+GetActualTextMatrix (HPDF_Page page);
+
+static HPDF_STATUS
+InternalWriteText (HPDF_Page page,
+ HPDF_BOOL fake_matrix_pos,
+ char oper);
static HPDF_STATUS
InternalArc (HPDF_Page page,
@@ -40,6 +66,13 @@ InternalArc (HPDF_Page page,
HPDF_REAL ang2,
HPDF_BOOL cont_flg);
+static HPDF_STATUS
+MoveTextPosAbs (HPDF_Page page,
+ HPDF_REAL xAbs,
+ HPDF_REAL yAbs,
+ HPDF_BOOL sideways,
+ HPDF_BOOL keep_line);
+
/*--- General graphics state ---------------------------------------------*/
@@ -1027,15 +1060,33 @@ HPDF_Page_SetCharSpace (HPDF_Page page,
if (value < HPDF_MIN_CHARSPACE || value > HPDF_MAX_CHARSPACE)
return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
+ attr->gstate->char_space = value;
+
+ if (attr->gstate->writing_mode == HPDF_WMODE_MIXED ||
+ attr->gstate->writing_mode == HPDF_WMODE_SIDEWAYS) {
+ attr->gstate->actual_font = NULL;
+ return HPDF_OK;
+ }
+
+ return SetCharSpace (page, attr->gstate->char_space);
+}
+
+static HPDF_STATUS
+SetCharSpace (HPDF_Page page,
+ HPDF_REAL value)
+{
+ HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
+
+ if (attr->gstate->writing_mode == HPDF_WMODE_MIXED)
+ value = -value;
+
if (HPDF_Stream_WriteReal (attr->stream, value) != HPDF_OK)
return HPDF_CheckError (page->error);
if (HPDF_Stream_WriteStr (attr->stream, " Tc\012") != HPDF_OK)
return HPDF_CheckError (page->error);
- attr->gstate->char_space = value;
-
- return ret;
+ return HPDF_OK;
}
/* Tw */
@@ -1057,15 +1108,33 @@ HPDF_Page_SetWordSpace (HPDF_Page page,
if (value < HPDF_MIN_WORDSPACE || value > HPDF_MAX_WORDSPACE)
return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
+ attr->gstate->word_space = value;
+
+ if (attr->gstate->writing_mode == HPDF_WMODE_MIXED ||
+ attr->gstate->writing_mode == HPDF_WMODE_SIDEWAYS) {
+ attr->gstate->actual_font = NULL;
+ return HPDF_OK;
+ }
+
+ return SetWordSpace (page, attr->gstate->word_space);
+}
+
+static HPDF_STATUS
+SetWordSpace (HPDF_Page page,
+ HPDF_REAL value)
+{
+ HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
+
+ if (attr->gstate->writing_mode == HPDF_WMODE_MIXED)
+ value = -value;
+
if (HPDF_Stream_WriteReal (attr->stream, value) != HPDF_OK)
return HPDF_CheckError (page->error);
if (HPDF_Stream_WriteStr (attr->stream, " Tw\012") != HPDF_OK)
return HPDF_CheckError (page->error);
- attr->gstate->word_space = value;
-
- return ret;
+ return HPDF_OK;
}
/* Tz */
@@ -1135,6 +1204,8 @@ HPDF_Page_SetFontAndSize (HPDF_Page page,
HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_PAGE_DESCRIPTION |
HPDF_GMODE_TEXT_OBJECT);
HPDF_PageAttr attr;
+ HPDF_Font oldfont;
+ HPDF_WritingMode oldwmode;
HPDF_PTRACE ((" HPDF_Page_SetFontAndSize\n"));
@@ -1152,70 +1223,146 @@ HPDF_Page_SetFontAndSize (HPDF_Page page,
attr = (HPDF_PageAttr)page->attr;
+ oldfont = attr->gstate->actual_font;
+ oldwmode = attr->gstate->writing_mode;
+
attr->gstate->font = font;
attr->gstate->font_size = size;
attr->gstate->actual_font = NULL;
- attr->gstate->writing_mode = ((HPDF_FontAttr)font->attr)->writing_mode;
+
+ if (!((HPDF_FontAttr)font->attr)->relief_font) {
+ attr->gstate->writing_mode = ((HPDF_FontAttr)font->attr)->writing_mode;
+ if ((ret = SetFontAndSize (page, font, 0, HPDF_FALSE, HPDF_FALSE))
+ != HPDF_OK)
+ return ret;
+ } else {
+ HPDF_Font rf;
+ attr->gstate->writing_mode = HPDF_WMODE_HORIZONTAL;
+ for (rf = font; rf; rf = ((HPDF_FontAttr)rf->attr)->relief_font) {
+ if (((HPDF_FontAttr)rf->attr)->writing_mode ==
+ HPDF_WMODE_VERTICAL) {
+ attr->gstate->writing_mode = HPDF_WMODE_MIXED;
+ break;
+ }
+ }
+ }
+
+ if ((attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL ||
+ attr->gstate->writing_mode == HPDF_WMODE_VERTICAL) &&
+ (oldwmode == HPDF_WMODE_MIXED ||
+ oldwmode == HPDF_WMODE_SIDEWAYS)) {
+ if (!oldfont || oldwmode == HPDF_WMODE_SIDEWAYS)
+ if ((ret = SetTextMatrix (page)) != HPDF_OK)
+ return ret;
+ if (!oldfont || (oldwmode == HPDF_WMODE_MIXED &&
+ attr->gstate->word_space))
+ if ((ret = SetWordSpace (page, attr->gstate->word_space))
+ != HPDF_OK)
+ return ret;
+ if (!oldfont || (oldwmode == HPDF_WMODE_MIXED &&
+ attr->gstate->char_space))
+ if ((ret = SetCharSpace (page, attr->gstate->char_space))
+ != HPDF_OK)
+ return ret;
+ if ((ret = SetTextRise (page)) != HPDF_OK)
+ return ret;
+ }
return ret;
}
+static HPDF_STATUS
+SetFontAndSize (HPDF_Page page,
+ HPDF_Font font,
+ HPDF_BYTE flags,
+ HPDF_BOOL set_word_char_space,
+ HPDF_BOOL move_to_text_pos)
+{
+ HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
+ HPDF_Font oldfont = attr->gstate->actual_font;
+ HPDF_REAL oldsize = attr->gstate->actual_font_size;
+ HPDF_REAL size = attr->gstate->font_size;
+ HPDF_WritingMode oldwmode = attr->gstate->writing_mode;
+ HPDF_STATUS ret = HPDF_OK;
-static HPDF_Font
-GetActualFont (HPDF_Page page,
- HPDF_UINT index)
-{
- HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
- HPDF_Font font;
+ if (flags & HPDF_INTERLINEAR_ANNOTATION)
+ size *= attr->gstate->ia_font_size_ratio;
- if (index == 0xFF)
- return attr->gstate->actual_font;
+ if (font != oldfont || size != oldsize) {
+ char buf[HPDF_TMP_BUF_SIZ];
+ char *pbuf = buf;
+ char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
+ const char *local_name;
- for (font = attr->gstate->font; index && font; index--)
- font = ((HPDF_FontAttr)font->attr)->relief_font;
+ local_name = HPDF_Page_GetLocalFontName (page, font);
- return font;
-}
+ if (!local_name)
+ return HPDF_RaiseError (page->error, HPDF_PAGE_INVALID_FONT, 0);
+ if (HPDF_Stream_WriteEscapeName (attr->stream, local_name) != HPDF_OK)
+ return HPDF_CheckError (page->error);
-static HPDF_STATUS
-SetActualFont (HPDF_Page page,
- HPDF_Font font)
-{
- HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
- char buf[HPDF_TMP_BUF_SIZ];
- char *pbuf = buf;
- char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
- const char *local_name;
+ HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
+ *pbuf++ = ' ';
+ pbuf = HPDF_FToA (pbuf, size, eptr);
+ HPDF_StrCpy (pbuf, " Tf\012", eptr);
- if (!HPDF_Font_Validate(font))
- return HPDF_RaiseError (page->error, HPDF_PAGE_INVALID_FONT, 0);
+ if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
+ return HPDF_CheckError (page->error);
- if (font == attr->gstate->actual_font)
- return HPDF_OK;
+ attr->gstate->actual_font = font;
+ attr->gstate->actual_font_size = size;
+ }
- attr->gstate->actual_font = font;
+ if (oldwmode == HPDF_WMODE_MIXED || oldwmode == HPDF_WMODE_SIDEWAYS) {
+ HPDF_FontAttr font_attr = (HPDF_FontAttr)font->attr;
- local_name = HPDF_Page_GetLocalFontName (page, font);
+ attr->gstate->writing_mode =
+ ((font_attr->writing_mode == HPDF_WMODE_HORIZONTAL)?
+ HPDF_WMODE_SIDEWAYS: HPDF_WMODE_MIXED);
- if (!local_name)
- return HPDF_RaiseError (page->error, HPDF_PAGE_INVALID_FONT, 0);
+ if (!oldfont || attr->gstate->writing_mode != oldwmode) {
+ if (move_to_text_pos) {
+ attr->text_matrix.x = attr->text_pos.x;
+ attr->text_matrix.y = attr->text_pos.y;
+ }
+ if ((ret = SetTextMatrix (page)) != HPDF_OK)
+ return ret;
+ }
+ if (!oldfont || attr->gstate->writing_mode != oldwmode ||
+ attr->gstate->writing_mode == HPDF_WMODE_SIDEWAYS)
+ if ((ret = SetTextRise (page)) != HPDF_OK)
+ return ret;
+ if (set_word_char_space?
+ (!oldfont || attr->gstate->writing_mode != oldwmode):
+ (attr->gstate->writing_mode == HPDF_WMODE_MIXED)) {
+ if (!oldfont || !set_word_char_space || attr->gstate->word_space)
+ if ((ret = SetWordSpace (page, attr->gstate->word_space))
+ != HPDF_OK)
+ return ret;
+ if (!oldfont || !set_word_char_space || attr->gstate->char_space)
+ if ((ret = SetCharSpace (page, attr->gstate->char_space))
+ != HPDF_OK)
+ return ret;
+ }
+ }
- if (HPDF_Stream_WriteEscapeName (attr->stream, local_name) != HPDF_OK)
- return HPDF_CheckError (page->error);
+ return HPDF_OK;
+}
- HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
- *pbuf++ = ' ';
- pbuf = HPDF_FToA (pbuf, attr->gstate->font_size, eptr);
- HPDF_StrCpy (pbuf, " Tf\012", eptr);
+static HPDF_Font
+GetActualFont (HPDF_Page page,
+ HPDF_UINT index)
+{
+ HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
+ HPDF_Font font;
- if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
- return HPDF_CheckError (page->error);
+ for (font = attr->gstate->font; index && font; index--)
+ font = ((HPDF_FontAttr)font->attr)->relief_font;
- return HPDF_OK;
+ return font;
}
-
/* Tr */
HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetTextRenderingMode (HPDF_Page page,
@@ -1255,7 +1402,6 @@ HPDF_Page_SetTextRaise (HPDF_Page page,
return HPDF_Page_SetTextRise (page, value);
}
-
HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetTextRise (HPDF_Page page,
HPDF_REAL value)
@@ -1271,17 +1417,53 @@ HPDF_Page_SetTextRise (HPDF_Page page,
attr = (HPDF_PageAttr)page->attr;
+ attr->gstate->text_rise = value;
+
+ if (attr->gstate->writing_mode == HPDF_WMODE_MIXED ||
+ attr->gstate->writing_mode == HPDF_WMODE_SIDEWAYS) {
+ attr->gstate->actual_font = NULL;
+ return HPDF_OK;
+ }
+
+ return SetTextRise (page);
+}
+
+static HPDF_STATUS
+SetTextRise (HPDF_Page page)
+{
+ HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
+ HPDF_REAL value;
+
+ if (attr->gstate->writing_mode == HPDF_WMODE_MIXED) {
+ value = 0;
+ } else {
+ value = attr->gstate->text_rise;
+
+ if (attr->gstate->writing_mode == HPDF_WMODE_SIDEWAYS &&
+ attr->gstate->actual_font_size == attr->gstate->font_size) {
+ HPDF_Font font = attr->gstate->actual_font;
+ HPDF_FontAttr font_attr;
+
+ if (!font)
+ return HPDF_OK;
+
+ font_attr = (HPDF_FontAttr)font->attr;
+ value -= ((font_attr->fontdef->font_bbox.top +
+ font_attr->fontdef->font_bbox.bottom) / 2 *
+ attr->gstate->font_size / 1000);
+ }
+ }
+
if (HPDF_Stream_WriteReal (attr->stream, value) != HPDF_OK)
return HPDF_CheckError (page->error);
if (HPDF_Stream_WriteStr (attr->stream, " Ts\012") != HPDF_OK)
return HPDF_CheckError (page->error);
- attr->gstate->text_rise = value;
-
- return ret;
+ return HPDF_OK;
}
+
/*--- Text positioning ---------------------------------------------------*/
/* Td */
@@ -1296,6 +1478,7 @@ HPDF_Page_MoveTextPos (HPDF_Page page,
char *pbuf = buf;
char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
HPDF_PageAttr attr;
+ HPDF_TransMatrix mat;
HPDF_PTRACE ((" HPDF_Page_MoveTextPos\n"));
@@ -1314,11 +1497,15 @@ HPDF_Page_MoveTextPos (HPDF_Page page,
if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
return HPDF_CheckError (page->error);
- attr->text_matrix.x += x * attr->text_matrix.a + y * attr->text_matrix.c;
- attr->text_matrix.y += y * attr->text_matrix.d + x * attr->text_matrix.b;
+ mat = GetActualTextMatrix (page);
+
+ attr->text_matrix.x += x * mat.a + y * mat.c;
+ attr->text_matrix.y += x * mat.b + y * mat.d;
attr->text_pos.x = attr->text_matrix.x;
attr->text_pos.y = attr->text_matrix.y;
+ attr->fake_text_pos = HPDF_FALSE;
+
return ret;
}
@@ -1333,6 +1520,7 @@ HPDF_Page_MoveTextPos2 (HPDF_Page page,
char *pbuf = buf;
char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
HPDF_PageAttr attr;
+ HPDF_TransMatrix mat;
HPDF_PTRACE ((" HPDF_Page_MoveTextPos2\n"));
@@ -1351,12 +1539,16 @@ HPDF_Page_MoveTextPos2 (HPDF_Page page,
if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
return HPDF_CheckError (page->error);
- attr->text_matrix.x += x * attr->text_matrix.a + y * attr->text_matrix.c;
- attr->text_matrix.y += y * attr->text_matrix.d + x * attr->text_matrix.b;
+ mat = GetActualTextMatrix (page);
+
+ attr->text_matrix.x += x * mat.a + y * mat.c;
+ attr->text_matrix.y += x * mat.b + y * mat.d;
attr->text_pos.x = attr->text_matrix.x;
attr->text_pos.y = attr->text_matrix.y;
attr->gstate->text_leading = -y;
+ attr->fake_text_pos = HPDF_FALSE;
+
return ret;
}
@@ -1371,9 +1563,6 @@ HPDF_Page_SetTextMatrix (HPDF_Page page,
HPDF_REAL y)
{
HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
- char buf[HPDF_TMP_BUF_SIZ];
- char *pbuf = buf;
- char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
HPDF_PageAttr attr;
HPDF_PTRACE ((" HPDF_Page_SetTextMatrix\n"));
@@ -1386,36 +1575,76 @@ HPDF_Page_SetTextMatrix (HPDF_Page page,
if ((a == 0 || d == 0) && (b == 0 || c == 0))
return HPDF_RaiseError (page->error, HPDF_INVALID_PARAMETER, 0);
- HPDF_MemSet (buf, 0, HPDF_TMP_BUF_SIZ);
+ attr->text_matrix.a = a;
+ attr->text_matrix.b = b;
+ attr->text_matrix.c = c;
+ attr->text_matrix.d = d;
+ attr->text_matrix.x = x;
+ attr->text_matrix.y = y;
+ attr->text_pos.x = attr->text_matrix.x;
+ attr->text_pos.y = attr->text_matrix.y;
- pbuf = HPDF_FToA (pbuf, a, eptr);
+ attr->fake_text_pos = HPDF_FALSE;
+
+ if (attr->gstate->writing_mode == HPDF_WMODE_MIXED ||
+ attr->gstate->writing_mode == HPDF_WMODE_SIDEWAYS) {
+ attr->gstate->actual_font = NULL;
+ return HPDF_OK;
+ }
+
+ return SetTextMatrix (page);
+}
+
+static HPDF_STATUS
+SetTextMatrix (HPDF_Page page)
+{
+ HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
+ HPDF_TransMatrix mat = GetActualTextMatrix (page);
+ char buf[HPDF_TMP_BUF_SIZ];
+ char *pbuf = buf;
+ char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
+
+ pbuf = HPDF_FToA (pbuf, mat.a, eptr);
*pbuf++ = ' ';
- pbuf = HPDF_FToA (pbuf, b, eptr);
+ pbuf = HPDF_FToA (pbuf, mat.b, eptr);
*pbuf++ = ' ';
- pbuf = HPDF_FToA (pbuf, c, eptr);
+ pbuf = HPDF_FToA (pbuf, mat.c, eptr);
*pbuf++ = ' ';
- pbuf = HPDF_FToA (pbuf, d, eptr);
+ pbuf = HPDF_FToA (pbuf, mat.d, eptr);
*pbuf++ = ' ';
- pbuf = HPDF_FToA (pbuf, x, eptr);
+ pbuf = HPDF_FToA (pbuf, mat.x, eptr);
*pbuf++ = ' ';
- pbuf = HPDF_FToA (pbuf, y, eptr);
+ pbuf = HPDF_FToA (pbuf, mat.y, eptr);
HPDF_StrCpy (pbuf, " Tm\012", eptr);
if (HPDF_Stream_WriteStr (attr->stream, buf) != HPDF_OK)
return HPDF_CheckError (page->error);
- attr->text_matrix.a = a;
- attr->text_matrix.b = b;
- attr->text_matrix.c = c;
- attr->text_matrix.d = d;
- attr->text_matrix.x = x;
- attr->text_matrix.y = y;
- attr->text_pos.x = attr->text_matrix.x;
- attr->text_pos.y = attr->text_matrix.y;
-
- return ret;
+ return HPDF_OK;
}
+static HPDF_TransMatrix
+GetActualTextMatrix (HPDF_Page page)
+{
+ HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
+ HPDF_TransMatrix mat;
+
+ if (attr->gstate->writing_mode != HPDF_WMODE_SIDEWAYS) {
+ mat.a = attr->text_matrix.a;
+ mat.b = attr->text_matrix.b;
+ mat.c = attr->text_matrix.c;
+ mat.d = attr->text_matrix.d;
+ } else {
+ mat.a = attr->text_matrix.b;
+ mat.b = -attr->text_matrix.a;
+ mat.c = attr->text_matrix.d;
+ mat.d = -attr->text_matrix.c;
+ }
+ mat.x = attr->text_matrix.x;
+ mat.y = attr->text_matrix.y;
+
+ return mat;
+}
/* T* */
HPDF_EXPORT(HPDF_STATUS)
@@ -1423,6 +1652,7 @@ HPDF_Page_MoveToNextLine (HPDF_Page page)
{
HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
HPDF_PageAttr attr;
+ HPDF_TransMatrix mat;
HPDF_PTRACE ((" HPDF_Page_MoveToNextLine\n"));
@@ -1431,16 +1661,23 @@ HPDF_Page_MoveToNextLine (HPDF_Page page)
attr = (HPDF_PageAttr)page->attr;
+ if (attr->gstate->writing_mode == HPDF_WMODE_MIXED)
+ return HPDF_Page_MoveTextPos (page, -attr->gstate->text_leading, 0);
+
if (HPDF_Stream_WriteStr (attr->stream, "T*\012") != HPDF_OK)
return HPDF_CheckError (page->error);
+ mat = GetActualTextMatrix (page);
+
/* calculate the reference point of text */
- attr->text_matrix.x -= attr->gstate->text_leading * attr->text_matrix.c;
- attr->text_matrix.y -= attr->gstate->text_leading * attr->text_matrix.d;
+ attr->text_matrix.x -= attr->gstate->text_leading * mat.c;
+ attr->text_matrix.y -= attr->gstate->text_leading * mat.d;
attr->text_pos.x = attr->text_matrix.x;
attr->text_pos.y = attr->text_matrix.y;
+ attr->fake_text_pos = HPDF_FALSE;
+
return ret;
}
@@ -1453,7 +1690,8 @@ HPDF_Page_ShowText (HPDF_Page page,
{
HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
HPDF_PageAttr attr;
- HPDF_REAL tw;
+ HPDF_Font font;
+ HPDF_BOOL fake_matrix_pos;
HPDF_PTRACE ((" HPDF_Page_ShowText\n"));
@@ -1461,22 +1699,36 @@ HPDF_Page_ShowText (HPDF_Page page,
return ret;
attr = (HPDF_PageAttr)page->attr;
+ font = attr->gstate->font;
/* no font exists */
- if (!attr->gstate->font)
+ if (!font)
return HPDF_RaiseError (page->error, HPDF_PAGE_FONT_NOT_FOUND, 0);
- tw = HPDF_Page_TextWidth (page, text);
- if (!tw)
+ fake_matrix_pos = HPDF_FALSE;
+ if (attr->fake_text_pos) {
+ HPDF_REAL x = attr->text_matrix.x;
+ HPDF_REAL y = attr->text_matrix.y;
+ if ((ret = MoveTextPosAbs (page, attr->text_pos.x, attr->text_pos.y,
+ HPDF_FALSE, HPDF_FALSE)) != HPDF_OK)
+ return ret;
+ attr->text_matrix.x = x;
+ attr->text_matrix.y = y;
+ fake_matrix_pos = HPDF_TRUE;
+ }
+
+ HPDF_Font_CheckBiDi (font, HPDF_FALSE);
+ if ((ret = HPDF_Font_ConvertText (font, 0, text, 0)) != HPDF_OK)
return ret;
- if (InternalWriteText (page, tw, NULL, NULL) != HPDF_OK)
+ if (InternalWriteText (page, fake_matrix_pos, 0) != HPDF_OK)
return HPDF_CheckError (page->error);
return ret;
}
-/* TJ */
+/* TJ --not implemented yet */
+
/* ' */
HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_ShowTextNextLine (HPDF_Page page,
@@ -1484,7 +1736,7 @@ HPDF_Page_ShowTextNextLine (HPDF_Page page,
{
HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
HPDF_PageAttr attr;
- HPDF_REAL tw;
+ HPDF_Font font;
HPDF_PTRACE ((" HPDF_Page_ShowTextNextLine\n"));
@@ -1492,19 +1744,20 @@ HPDF_Page_ShowTextNextLine (HPDF_Page page,
return ret;
attr = (HPDF_PageAttr)page->attr;
+ font = attr->gstate->font;
/* no font exists */
- if (!attr->gstate->font)
+ if (!font)
return HPDF_RaiseError (page->error, HPDF_PAGE_FONT_NOT_FOUND, 0);
- if (text && !HPDF_Font_StrLen ((HPDF_Font)attr->gstate->font, text, 4))
+ if (text && !HPDF_Font_StrLen (font, text, 4))
return HPDF_Page_MoveToNextLine(page);
- tw = HPDF_Page_TextWidth (page, text);
- if (!tw)
- return HPDF_Page_MoveToNextLine(page);
+ HPDF_Font_CheckBiDi (font, HPDF_FALSE);
+ if ((ret = HPDF_Font_ConvertText (font, 0, text, 0)) != HPDF_OK)
+ return ret;
- if (InternalWriteText (page, tw, NULL, " \'\012") != HPDF_OK)
+ if (InternalWriteText (page, HPDF_FALSE, '\'') != HPDF_OK)
return HPDF_CheckError (page->error);
return ret;
@@ -1519,10 +1772,7 @@ HPDF_Page_ShowTextNextLineEx (HPDF_Page page,
{
HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
HPDF_PageAttr attr;
- HPDF_REAL tw;
- char buf[HPDF_TMP_BUF_SIZ];
- char *pbuf = buf;
- char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
+ HPDF_Font font;
HPDF_PTRACE ((" HPDF_Page_ShowTextNextLineEX\n"));
@@ -1536,28 +1786,23 @@ HPDF_Page_ShowTextNextLineEx (HPDF_Page page,
return HPDF_RaiseError (page->error, HPDF_PAGE_OUT_OF_RANGE, 0);
attr = (HPDF_PageAttr)page->attr;
+ font = attr->gstate->font;
/* no font exists */
- if (!attr->gstate->font)
+ if (!font)
return HPDF_RaiseError (page->error, HPDF_PAGE_FONT_NOT_FOUND, 0);
- if (text && !HPDF_Font_StrLen ((HPDF_Font)attr->gstate->font, text, 4))
+ if (text && !HPDF_Font_StrLen (font, text, 4))
return HPDF_Page_MoveToNextLine(page);
- pbuf = HPDF_FToA (pbuf, word_space, eptr);
- *pbuf++ = ' ';
- pbuf = HPDF_FToA (pbuf, char_space, eptr);
- *pbuf++ = ' ';
- *pbuf = 0;
-
attr->gstate->word_space = word_space;
attr->gstate->char_space = char_space;
- tw = HPDF_Page_TextWidth (page, text);
- if (!tw)
- return HPDF_Page_MoveToNextLine(page);
+ HPDF_Font_CheckBiDi (font, HPDF_FALSE);
+ if ((ret = HPDF_Font_ConvertText (font, 0, text, 0)) != HPDF_OK)
+ return ret;
- if (InternalWriteText (page, tw, buf, " \"\012") != HPDF_OK)
+ if (InternalWriteText (page, HPDF_FALSE, '\"') != HPDF_OK)
return HPDF_CheckError (page->error);
return ret;
@@ -1574,7 +1819,6 @@ HPDF_Page_ShowTextNextLineEx (HPDF_Page page,
/* SCN --not implemented yet */
/* g */
-
HPDF_EXPORT(HPDF_STATUS)
HPDF_Page_SetGrayFill (HPDF_Page page,
HPDF_REAL gray)
@@ -2312,39 +2556,194 @@ HPDF_Page_DrawImage (HPDF_Page page,
static HPDF_STATUS
-InternalWriteText (HPDF_Page page,
- HPDF_REAL tw,
- const char *prefix,
- const char *operator)
+InternalWriteText (HPDF_Page page,
+ HPDF_BOOL fake_matrix_pos,
+ char oper)
{
- HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
+ HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
HPDF_FontAttr font_attr = (HPDF_FontAttr)attr->gstate->font->attr;
+ HPDF_Point line_start_pos, text_start_pos;
HPDF_STATUS ret;
HPDF_UINT i, n;
- HPDF_BYTE *pirf;
+ HPDF_BYTE *pirf, flags, nflags;
+ HPDF_REAL tw, tw_ia, rise_ia;
+ char op_buf[] = " ?\012";
+ const char *op_Tj = " Tj\012";
+ const char *op = op_Tj;
HPDF_PTRACE ((" InternalWriteText\n"));
+ flags = 0;
+ tw_ia = tw = 0;
+ rise_ia = 0;
+
+ line_start_pos.x = attr->text_matrix.x;
+ line_start_pos.y = attr->text_matrix.y;
+ text_start_pos = attr->text_pos;
+ if (fake_matrix_pos) {
+ attr->text_matrix.x = text_start_pos.x;
+ attr->text_matrix.y = text_start_pos.y;
+ }
+
+ if (oper) {
+ op_buf[1] = oper;
+ op = op_buf;
+ }
+
pirf = font_attr->text_cache +
(font_attr->text_cache_allocated / 2);
- for (i = 0, n = 1; n <= font_attr->text_cache_len; n++) {
+ for (i = 0, n = 0; n <= font_attr->text_cache_len; n++) {
HPDF_Font rf;
HPDF_FontAttr rf_attr;
+ HPDF_REAL rw;
- if (n < font_attr->text_cache_len &&
- (pirf[n] == 0xFF || pirf[n] == pirf[i]))
+ if (n < font_attr->text_cache_len && pirf[n] == pirf[i])
continue;
- rf = GetActualFont (page, pirf[i]);
- rf_attr = (HPDF_FontAttr)rf->attr;
+ rf = GetActualFont (page, pirf[i] & HPDF_RELIEF_FONT_INDEX_MASK);
+ nflags = pirf[i] & ~HPDF_RELIEF_FONT_INDEX_MASK;
- if ((ret = SetActualFont (page, rf)) != HPDF_OK)
+ if ((ret = SetFontAndSize (page, rf, nflags,
+ (op[1] != '\"'),
+ (op[1] != '\"' && op[1] != '\''))) != HPDF_OK)
return ret;
- if (!i && prefix)
- if ((ret = HPDF_Stream_WriteStr (attr->stream, prefix)) != HPDF_OK)
+ if (nflags != flags) {
+ if (!(flags & HPDF_INTERLINEAR_ANNOTATED) &&
+ (nflags & HPDF_INTERLINEAR_ANNOTATED)) {
+ HPDF_Box bbox = HPDF_Font_GetBBox (rf);
+ if (attr->gstate->writing_mode == HPDF_WMODE_MIXED)
+ rise_ia = (bbox.right - bbox.left) * 0.5F;
+ else if (attr->gstate->writing_mode == HPDF_WMODE_SIDEWAYS)
+ rise_ia = (bbox.top - bbox.bottom) * 0.5F;
+ else
+ rise_ia = bbox.top;
+ rise_ia *= attr->gstate->font_size / 1000;
+ tw_ia = tw;
+ }
+ if (!(flags & HPDF_INTERLINEAR_ANNOTATION) &&
+ (nflags & HPDF_INTERLINEAR_ANNOTATION)) {
+ HPDF_REAL aw, rise, dx, dy, x, y;
+ HPDF_Box bbox = HPDF_Font_GetBBox (rf);
+ HPDF_TextWidth w = HPDF_Font_TextCacheWidth (attr->gstate->font,
+ HPDF_TRUE, i, n);
+ aw = w.width * attr->gstate->actual_font_size / 1000;
+ tw_ia += ((tw - tw_ia) / 2) - (aw / 2);
+ if (attr->gstate->writing_mode == HPDF_WMODE_MIXED)
+ rise = (bbox.right - bbox.left) * 0.5F;
+ else
+ rise = -bbox.bottom;
+ rise_ia += rise * attr->gstate->actual_font_size / 1000;
+ if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
+ dx = tw_ia;
+ dy = rise_ia;
+ } else {
+ dx = rise_ia;
+ dy = -tw_ia;
+ }
+ x = text_start_pos.x;
+ y = text_start_pos.y;
+ x += (dx * attr->text_matrix.a) + (dy * attr->text_matrix.c);
+ y += (dx * attr->text_matrix.b) + (dy * attr->text_matrix.d);
+ if ((ret = MoveTextPosAbs (page, x, y, HPDF_FALSE, HPDF_FALSE))
+ != HPDF_OK)
+ return ret;
+ if (attr->gstate->word_space &&
+ (ret = SetWordSpace (page, 0)) != HPDF_OK)
+ return ret;
+ if (attr->gstate->char_space &&
+ (ret = SetCharSpace (page, 0)) != HPDF_OK)
+ return ret;
+ tw_ia = tw;
+ }
+ if ( (flags & HPDF_INTERLINEAR_ANNOTATION) &&
+ !(nflags & HPDF_INTERLINEAR_ANNOTATION)) {
+ HPDF_REAL dx, dy, x, y;
+ if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
+ dx = tw_ia;
+ dy = 0;
+ } else {
+ dx = 0;
+ dy = -tw_ia;
+ }
+ x = text_start_pos.x;
+ y = text_start_pos.y;
+ x += (dx * attr->text_matrix.a) + (dy * attr->text_matrix.c);
+ y += (dx * attr->text_matrix.b) + (dy * attr->text_matrix.d);
+ if ((ret = MoveTextPosAbs (page, x, y, HPDF_FALSE, HPDF_FALSE))
+ != HPDF_OK)
+ return ret;
+ if (attr->gstate->word_space &&
+ (ret = SetWordSpace (page, attr->gstate->word_space))
+ != HPDF_OK)
+ return ret;
+ if (attr->gstate->char_space &&
+ (ret = SetCharSpace (page, attr->gstate->char_space))
+ != HPDF_OK)
+ return ret;
+ }
+ flags = nflags;
+ }
+
+ rw = 0;
+ if (!(flags & HPDF_INTERLINEAR_ANNOTATION)) {
+ HPDF_TextWidth w = HPDF_Font_TextCacheWidth (attr->gstate->font,
+ HPDF_FALSE, i, n);
+ rw = ((w.width * attr->gstate->font_size / 1000) +
+ (w.numspace * attr->gstate->word_space) +
+ (w.numchars * attr->gstate->char_space));
+ tw += rw;
+ }
+
+ if (op[1] == '\'' || op[1] == '\"') {
+ if (attr->gstate->writing_mode == HPDF_WMODE_MIXED) {
+ op = op_Tj;
+ if ((ret = HPDF_Page_MoveTextPos (page,
+ -attr->gstate->text_leading, 0)) != HPDF_OK)
+ return ret;
+ } else {
+ if (attr->gstate->writing_mode == HPDF_WMODE_SIDEWAYS) {
+ attr->text_matrix.x -=
+ attr->gstate->text_leading * attr->text_matrix.a;
+ attr->text_matrix.y -=
+ attr->gstate->text_leading * attr->text_matrix.b;
+ } else {
+ attr->text_matrix.x -=
+ attr->gstate->text_leading * attr->text_matrix.c;
+ attr->text_matrix.y -=
+ attr->gstate->text_leading * attr->text_matrix.d;
+ }
+ attr->text_pos.x = attr->text_matrix.x;
+ attr->text_pos.y = attr->text_matrix.y;
+ }
+ text_start_pos = line_start_pos = attr->text_pos;
+ }
+ if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
+ attr->text_pos.x += rw * attr->text_matrix.a;
+ attr->text_pos.y += rw * attr->text_matrix.b;
+ } else {
+ attr->text_pos.x -= rw * attr->text_matrix.c;
+ attr->text_pos.y -= rw * attr->text_matrix.d;
+ }
+
+ if (op[1] == '\"') {
+ char buf[HPDF_TMP_BUF_SIZ];
+ char *pbuf;
+ char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
+
+ pbuf = buf;
+ pbuf = HPDF_FToA (pbuf, attr->gstate->word_space, eptr);
+ *pbuf++ = ' ';
+ pbuf = HPDF_FToA (pbuf, attr->gstate->char_space, eptr);
+ *pbuf++ = ' ';
+ *pbuf = 0;
+
+ if ((ret = HPDF_Stream_WriteStr (attr->stream, buf)) != HPDF_OK)
return ret;
+ }
+
+ rf_attr = (HPDF_FontAttr)rf->attr;
if (rf_attr->type == HPDF_FONT_TYPE0_TT ||
rf_attr->type == HPDF_FONT_TYPE0_CID) {
@@ -2353,18 +2752,18 @@ InternalWriteText (HPDF_Page page,
if ((ret = HPDF_Stream_WriteStr (attr->stream, "<")) != HPDF_OK)
return ret;
-
+
if (rf_attr->type == HPDF_FONT_TYPE0_TT)
ttfontdef_attr = (HPDF_TTFontDefAttr)rf_attr->fontdef->attr;
if (ttfontdef_attr &&
- !(ttfontdef_attr->options & HPDF_FONTOPT_WITH_CID_MAP))
+ (ttfontdef_attr->options & HPDF_FONTOPT_WITHOUT_CID_MAP))
encoder = rf_attr->encoder;
if ((ret = HPDF_Stream_WriteBinary (attr->stream,
font_attr->text_cache + i, n - i, NULL, encoder))
!= HPDF_OK)
return ret;
-
+
if ((ret = HPDF_Stream_WriteStr (attr->stream, ">")) != HPDF_OK)
return ret;
} else {
@@ -2373,28 +2772,29 @@ InternalWriteText (HPDF_Page page,
return ret;
}
- if ((ret = HPDF_Stream_WriteStr (attr->stream,
- ((i || !operator)? " Tj\012": operator))) != HPDF_OK)
+ if ((ret = HPDF_Stream_WriteStr (attr->stream, op)) != HPDF_OK)
return ret;
+ op = op_Tj;
i = n;
}
- /* calculate the reference point of text */
- if (operator) {
- attr->text_matrix.x -= attr->gstate->text_leading * attr->text_matrix.c;
- attr->text_matrix.y -= attr->gstate->text_leading * attr->text_matrix.d;
-
- attr->text_pos.x = attr->text_matrix.x;
- attr->text_pos.y = attr->text_matrix.y;
- }
-
- if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
- attr->text_pos.x += tw * attr->text_matrix.a;
- attr->text_pos.y += tw * attr->text_matrix.b;
- } else {
- attr->text_pos.x -= tw * attr->text_matrix.b;
- attr->text_pos.y -= tw * attr->text_matrix.a;
+ attr->fake_text_pos = HPDF_FALSE;
+ if (fake_matrix_pos ||
+ attr->text_matrix.x != line_start_pos.x ||
+ attr->text_matrix.y != line_start_pos.y) {
+ if ((ret = MoveTextPosAbs (page, line_start_pos.x, line_start_pos.y,
+ HPDF_FALSE, HPDF_FALSE)) != HPDF_OK)
+ return ret;
+ attr->text_pos = text_start_pos;
+ if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
+ attr->text_pos.x += tw * attr->text_matrix.a;
+ attr->text_pos.y += tw * attr->text_matrix.b;
+ } else {
+ attr->text_pos.x -= tw * attr->text_matrix.c;
+ attr->text_pos.y -= tw * attr->text_matrix.d;
+ }
+ attr->fake_text_pos = HPDF_TRUE;
}
return HPDF_OK;
@@ -2402,29 +2802,46 @@ InternalWriteText (HPDF_Page page,
/*
- * Convert a user space text position from absolute to relative coordinates.
- * Absolute values are passed in xAbs and yAbs, relative values are returned
- * to xRel and yRel. The latter two must not be NULL.
+ * Convert a user space text position from absolute to relative coordinates,
+ * and move text position.
+ * Absolute values are passed in xAbs and yAbs.
*/
-static void
-TextPos_AbsToRel (HPDF_TransMatrix text_matrix,
- HPDF_REAL xAbs,
- HPDF_REAL yAbs,
- HPDF_REAL *xRel,
- HPDF_REAL *yRel)
-{
- if (text_matrix.a == 0) {
- *xRel = (yAbs - text_matrix.y - (xAbs - text_matrix.x) *
- text_matrix.d / text_matrix.c) / text_matrix.b;
- *yRel = (xAbs - text_matrix.x) / text_matrix.c;
+static HPDF_STATUS
+MoveTextPosAbs (HPDF_Page page,
+ HPDF_REAL xAbs,
+ HPDF_REAL yAbs,
+ HPDF_BOOL sideways,
+ HPDF_BOOL keep_line)
+{
+ HPDF_PageAttr attr = (HPDF_PageAttr)page->attr;
+ HPDF_TransMatrix mat = GetActualTextMatrix (page);
+ HPDF_REAL x, y;
+
+ if (sideways &&
+ (attr->gstate->writing_mode == HPDF_WMODE_MIXED ||
+ attr->gstate->writing_mode == HPDF_WMODE_SIDEWAYS)) {
+ HPDF_REAL tmp = -xAbs;
+ xAbs = yAbs;
+ yAbs = tmp;
+ }
+
+ if (mat.a == 0) {
+ x = (yAbs - mat.y - (xAbs - mat.x) * mat.d / mat.c) / mat.b;
+ y = (xAbs - mat.x) / mat.c;
} else {
- HPDF_REAL y = (yAbs - text_matrix.y - (xAbs - text_matrix.x) *
- text_matrix.b / text_matrix.a) / (text_matrix.d -
- text_matrix.c * text_matrix.b / text_matrix.a);
- *xRel = (xAbs - text_matrix.x - y * text_matrix.c) /
- text_matrix.a;
- *yRel = y;
+ y = ((yAbs - mat.y - (xAbs - mat.x) * mat.b / mat.a) /
+ (mat.d - mat.c * mat.b / mat.a));
+ x = (xAbs - mat.x - y * mat.c) / mat.a;
+ }
+
+ if (keep_line) {
+ if (sideways && attr->gstate->writing_mode == HPDF_WMODE_MIXED)
+ x = 0;
+ else
+ y = 0;
}
+
+ return HPDF_Page_MoveTextPos (page, x, y);
}
@@ -2435,8 +2852,6 @@ HPDF_Page_TextOut (HPDF_Page page,
const char *text)
{
HPDF_STATUS ret = HPDF_Page_CheckState (page, HPDF_GMODE_TEXT_OBJECT);
- HPDF_REAL x;
- HPDF_REAL y;
HPDF_PageAttr attr;
HPDF_PTRACE ((" HPDF_Page_TextOut\n"));
@@ -2445,8 +2860,8 @@ HPDF_Page_TextOut (HPDF_Page page,
return ret;
attr = (HPDF_PageAttr)page->attr;
- TextPos_AbsToRel (attr->text_matrix, xpos, ypos, &x, &y);
- if ((ret = HPDF_Page_MoveTextPos (page, x, y)) != HPDF_OK)
+ if ((ret = MoveTextPosAbs (page, xpos, ypos, HPDF_FALSE, HPDF_FALSE))
+ != HPDF_OK)
return ret;
return HPDF_Page_ShowText (page, text);
@@ -2469,19 +2884,18 @@ HPDF_Page_TextRect (HPDF_Page page,
const char *ptr = text;
HPDF_BOOL pos_initialized = HPDF_FALSE;
HPDF_BOOL pos_for_rtl = HPDF_FALSE;
- HPDF_BOOL is_insufficient_space = HPDF_FALSE;
HPDF_UINT num_rest;
HPDF_Box bbox;
HPDF_BOOL bidi_each_paragraph = HPDF_FALSE;
HPDF_BOOL remove_tatweel = HPDF_FALSE;
HPDF_INT meas_opt;
- HPDF_REAL word_space;
- HPDF_REAL char_space;
- const char *operator;
- char buf[HPDF_TMP_BUF_SIZ];
- char *pbuf = NULL;
- char *eptr = buf + sizeof buf - 1;
- HPDF_REAL save_text_leading, text_leading;
+ HPDF_REAL save_word_space, save_char_space;
+ HPDF_REAL save_leading, text_leading, min_leading;
+ HPDF_REAL except_bottom_line;
+ HPDF_UINT max_lines, lines, line;
+ HPDF_TextLineWidth *text_line_width, *tlw;
+ HPDF_TextAlignment page_align;
+ char oper;
HPDF_PTRACE ((" HPDF_Page_TextRect\n"));
@@ -2496,26 +2910,42 @@ HPDF_Page_TextRect (HPDF_Page page,
return HPDF_RaiseError (page->error, HPDF_PAGE_FONT_NOT_FOUND, 0);
}
- if (align & HPDF_TALIGNOPT_BIDI_EACH_PARAGRAPH)
+ if (align & HPDF_ALIGNOPT_BIDI_EACH_PARAGRAPH)
bidi_each_paragraph = HPDF_TRUE;
- if (align & HPDF_TALIGNOPT_REMOVE_TATWEEL)
+ if (align & HPDF_ALIGNOPT_REMOVE_TATWEEL)
remove_tatweel = HPDF_TRUE;
- align &= HPDF_TALIGN_MASK;
+ page_align = align;
+ if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL ||
+ attr->gstate->writing_mode == HPDF_WMODE_VERTICAL) {
+ page_align >>= 8;
+ } else {
+ HPDF_REAL tmp;
+ tmp = top;
+ top = right;
+ right = -bottom;
+ bottom = left;
+ left = -tmp;
+ align >>= 8;
+ }
+ align &= HPDF_TALIGN_MASK;
+ page_align &= HPDF_TALIGN_MASK;
- operator = " \'\012";
meas_opt = HPDF_MEASURE_WORD_WRAP;
- if (align == HPDF_TALIGN_JUSTIFY ||
- align == HPDF_TALIGN_JUSTIFY_ALL ||
- align == HPDF_TALIGN_STRETCH) {
- operator = " \"\012";
- if (align != HPDF_TALIGN_STRETCH)
+ if (remove_tatweel)
+ meas_opt |= HPDF_MEASURE_IGNORE_TATWEEL;
+
+ oper = '\'';
+ switch (align) {
+ case HPDF_TALIGN_JUSTIFY:
+ case HPDF_TALIGN_JUSTIFY_ALL:
meas_opt |= HPDF_MEASURE_CAN_SHORTEN;
- if (remove_tatweel)
- meas_opt |= HPDF_MEASURE_IGNORE_TATWEEL;
+ /* not break */
+ case HPDF_TALIGN_STRETCH:
+ case HPDF_TALIGN_STRETCH_ALL:
+ oper = '\"';
+ break;
}
- bbox = HPDF_Font_GetBBox (font);
-
if (len)
*len = 0;
num_rest = HPDF_Font_StrLen (font, text, HPDF_LIMIT_MAX_STRING_LEN + 1);
@@ -2525,323 +2955,260 @@ HPDF_Page_TextRect (HPDF_Page page,
} else if (!num_rest)
return HPDF_OK;
- save_text_leading = text_leading = attr->gstate->text_leading;
-
- if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
- if (text_leading == 0) {
- text_leading = (bbox.top - bbox.bottom) / 1000 *
- attr->gstate->font_size;
- HPDF_Page_SetTextLeading (page, text_leading);
- }
+ save_leading = attr->gstate->text_leading;
+ save_word_space = attr->gstate->word_space;
+ save_char_space = attr->gstate->char_space;
- top -= bbox.top / 1000 * attr->gstate->font_size - text_leading;
- bottom -= bbox.bottom / 1000 * attr->gstate->font_size;
- } else {
- HPDF_REAL cw;
- HPDF_REAL tmp = top;
- top = right;
- right = -bottom;
- bottom = left;
- left = -tmp;
+ bbox = HPDF_Font_GetBBox (font);
- if (text_leading == 0)
- text_leading = (bbox.right - bbox.left) / 1000 *
- attr->gstate->font_size;
+ min_leading = (bbox.top - bbox.bottom) / 1000 * attr->gstate->font_size;
+ except_bottom_line = top - bottom - min_leading;
+ if (except_bottom_line < 0)
+ return HPDF_PAGE_INSUFFICIENT_SPACE;
+ if (save_leading == 0)
+ save_leading = min_leading; /* for backward compatibility */
+ text_leading = ((save_leading < 0)? -save_leading: save_leading);
+ if (min_leading < text_leading &&
+ (page_align == HPDF_TALIGN_JUSTIFY ||
+ page_align == HPDF_TALIGN_JUSTIFY_ALL))
+ text_leading = min_leading;
+ max_lines = (HPDF_UINT)(except_bottom_line / text_leading) + 1;
+ if (1 < max_lines &&
+ (page_align == HPDF_TALIGN_JUSTIFY ||
+ page_align == HPDF_TALIGN_STRETCH))
+ text_leading = except_bottom_line / (max_lines - 1);
+
+ if (!(text_line_width = HPDF_GetMem (page->mmgr, max_lines * sizeof *tlw)))
+ return page->mmgr->error->error_no;
+ lines = HPDF_Page_MeasureTextLines (page, ptr, right - left, meas_opt,
+ text_line_width, max_lines);
+ if (!lines)
+ goto END;
+
+ if (1 < lines &&
+ (page_align == HPDF_TALIGN_JUSTIFY_ALL ||
+ page_align == HPDF_TALIGN_STRETCH_ALL))
+ text_leading = except_bottom_line / (lines - 1);
+ if (save_leading < 0) {
+ except_bottom_line = -except_bottom_line;
+ text_leading = -text_leading;
+ min_leading = -min_leading;
+ top = bottom;
+ }
+ if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL ||
+ attr->gstate->writing_mode == HPDF_WMODE_VERTICAL) {
+ if (0 < text_leading)
+ top -= (bbox.top / 1000 * attr->gstate->font_size);
else
- HPDF_Page_SetTextLeading (page, 0);
-
- cw = (bbox.right - bbox.left) / 1000 * attr->gstate->font_size;
- top -= cw / 2;
- bottom -= cw / 2;
- if (text_leading < 0) {
- tmp = top;
- top = bottom;
- bottom = tmp;
- top += cw;
- }
+ top -= (bbox.bottom / 1000 * attr->gstate->font_size);
+ } else {
+ top -= (min_leading / 2);
}
+ if (page_align == HPDF_TALIGN_RIGHT)
+ top -= except_bottom_line - (text_leading * (lines - 1));
+ else if (page_align == HPDF_TALIGN_CENTER)
+ top -= (except_bottom_line - (text_leading * (lines - 1))) / 2;
+ top += text_leading;
- word_space = attr->gstate->word_space;
- char_space = attr->gstate->char_space;
+ if (text_leading != attr->gstate->text_leading)
+ HPDF_Page_SetTextLeading (page, text_leading);
HPDF_Font_CheckBiDi (font, bidi_each_paragraph);
- for (;;) {
- HPDF_REAL x, y;
- HPDF_UINT line_len, tmp_len;
- HPDF_UINT numchars, numspaces, numtatweels;
- HPDF_REAL rw;
- HPDF_BOOL line_break, justify;
- HPDF_UCS4 ucs4 = 0;
-
- line_len = HPDF_Page_MeasureTextEx (page, ptr, right - left, meas_opt,
- &rw, &tmp_len, &numchars, &numspaces, &numtatweels);
-
- if (line_len == 0) {
- is_insufficient_space = HPDF_TRUE;
- break;
- }
+ for (line = 0, tlw = text_line_width; line < lines; line++, tlw++) {
+ HPDF_REAL drw;
+ HPDF_BOOL line_break = HPDF_FALSE;
+ HPDF_BOOL justify = HPDF_FALSE;
if (len)
- *len += line_len;
- num_rest -= line_len;
-
- /* Shorten tmp_len by trailing whitespace and control characters. */
- line_break = HPDF_FALSE;
- if (tmp_len < line_len) {
- ucs4 = HPDF_Font_GetUcs4 (font, ptr + tmp_len, NULL);
- if (ucs4 == 0x0A || ucs4 == 0x0C || ucs4 == 0x0D)
- line_break = HPDF_TRUE;
- }
+ *len += tlw->linebytes;
+ num_rest -= tlw->linebytes;
- if (!tmp_len) {
- if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL)
- ret = HPDF_Page_MoveToNextLine(page);
- else
- ret = HPDF_Page_MoveTextPos (page, -text_leading, 0);
- if (ret != HPDF_OK)
- return ret;
+ if (tlw->flags & HPDF_TLW_PRAGRAPH_BREAK)
+ line_break = HPDF_TRUE;
+ if (tlw->flags & HPDF_TLW_PAGE_BREAK)
+ num_rest = 0;
- if (num_rest <= 0 || ucs4 == 0x0C)
- break;
+ if (!tlw->numbytes) {
+ if ((ret = HPDF_Page_MoveToNextLine(page)) != HPDF_OK)
+ goto END;
- ptr += line_len;
+ ptr += tlw->linebytes;
continue;
}
- switch (align) {
+ attr->gstate->word_space = save_word_space;
+ attr->gstate->char_space = save_char_space;
- case HPDF_TALIGN_RIGHT:
- if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
- TextPos_AbsToRel (attr->text_matrix,
- right - rw, top, &x, &y);
- if (pos_initialized)
- y = 0;
- } else {
- TextPos_AbsToRel (attr->text_matrix,
- top, -(right - rw), &x, &y);
- if (pos_initialized)
- x = -text_leading;
- }
- if ((ret = HPDF_Page_MoveTextPos (page, x, y)) != HPDF_OK)
- return ret;
- pos_initialized = HPDF_TRUE;
- break;
+ drw = right - left - tlw->width;
- case HPDF_TALIGN_CENTER:
- if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
- TextPos_AbsToRel (attr->text_matrix,
- left + (right - left - rw) / 2, top, &x, &y);
- if (pos_initialized)
- y = 0;
- } else {
- TextPos_AbsToRel (attr->text_matrix,
- top, -(left + (right - left - rw) / 2), &x, &y);
- if (pos_initialized)
- x = -text_leading;
- }
- if ((ret = HPDF_Page_MoveTextPos (page, x, y)) != HPDF_OK)
- return ret;
- pos_initialized = HPDF_TRUE;
- break;
-
- case HPDF_TALIGN_JUSTIFY:
+ switch (align) {
case HPDF_TALIGN_JUSTIFY_ALL:
+ case HPDF_TALIGN_STRETCH_ALL:
+ justify = HPDF_TRUE;
+ /* not break */
+ case HPDF_TALIGN_JUSTIFY:
case HPDF_TALIGN_STRETCH:
- word_space = attr->gstate->word_space;
- char_space = attr->gstate->char_space;
-
/* Do not justify last line of paragraph or text. */
- justify = (align == HPDF_TALIGN_JUSTIFY_ALL ||
- !((line_break || num_rest <= 0) && rw < right - left));
- if (justify) {
- HPDF_REAL ch, sp, tt, all, ttw;
-
- if (attr->gstate->writing_mode == HPDF_WMODE_VERTICAL) {
- char_space *= -1;
- word_space *= -1;
- }
+ if ((!line_break && num_rest) || drw < 0)
+ justify = HPDF_TRUE;
- if (numchars <= 1)
- numchars = 0;
- else
- numchars--;
-
- ch = numchars * attr->gstate->justify_char_space;
- sp = numspaces * attr->gstate->justify_word_space;
- tt = numtatweels * attr->gstate->justify_kashida;
- if (tt) {
- ttw = ((HPDF_REAL)HPDF_Font_GetUcs4Width (font, 0x0640)
- * attr->gstate->font_size / 1000) + char_space;
- if (remove_tatweel) {
- tt *= ttw;
- rw += ttw * numtatweels;
- }
- }
- if (!ch && !sp && !tt)
+ if (justify) {
+ HPDF_REAL ch, sp, tt, all, dch, dsp, dtt;
+ HPDF_UINT numchars = ((tlw->numchars <= 1)? 0:
+ (tlw->numchars - 1));
+
+ ch = numchars * attr->gstate->justify_char_space;
+ sp = tlw->numspaces * attr->gstate->justify_word_space;
+ tt = tlw->numtatweels * attr->gstate->justify_kashida;
+ all = ch + sp + tt;
+ if (!all) {
all = ch = 1;
- else
- all = ch + sp + tt;
-
- all = (right - left - rw) / all;
- ch *= all;
- sp *= all;
- tt *= all;
+ sp = tt = 0;
+ }
+ dch = drw * ch / all;
+ dsp = drw * sp / all;
+ dtt = drw * tt / all;
if (tt) {
+ HPDF_REAL ttw;
HPDF_INT tatweels;
HPDF_UINT dst_tatweels;
- tatweels = (HPDF_INT)((tt / ttw) + numtatweels);
+ ttw = ((HPDF_REAL)HPDF_Font_GetUcs4Width (font, 0x0640)
+ * attr->gstate->font_size / 1000)
+ + attr->gstate->char_space;
+ if (remove_tatweel)
+ tatweels = (HPDF_INT)(dtt / ttw);
+ else
+ tatweels =
+ (HPDF_INT)((dtt / ttw) + tlw->numtatweels);
if (tatweels < 0)
tatweels = 0;
dst_tatweels = (HPDF_UINT)tatweels;
- if (dst_tatweels != numtatweels)
+ if (dst_tatweels != tlw->numtatweels)
HPDF_Font_SetTatweelCount (font, dst_tatweels,
- numtatweels, numchars);
- tatweels -= (HPDF_INT)numtatweels;
- ttw = tt - (tatweels * ttw);
- if (sp)
- sp += ttw;
- else
- ch += ttw;
+ tlw->numtatweels, tlw->numchars);
+ if (!remove_tatweel)
+ tatweels -= (HPDF_INT)tlw->numtatweels;
+ dtt -= tatweels * ttw;
+ if (!sp) {
+ dch += dtt;
+ } else {
+ dch += dtt * ch / (ch + sp);
+ dsp += dtt * sp / (ch + sp);
+ }
numchars += tatweels;
+ } else if (remove_tatweel && tlw->numtatweels) {
+ HPDF_Font_SetTatweelCount (font, 0,
+ tlw->numtatweels, tlw->numchars);
}
- if (ch < 0 && (char_space * numchars) + ch < 0 && sp) {
- if (0 < char_space) {
- sp += (char_space * numchars) + ch;
- char_space = 0;
+ if (dsp && tlw->numspaces && dch < 0 &&
+ (attr->gstate->char_space * numchars) + dch < 0) {
+ if (0 < attr->gstate->char_space) {
+ dsp += (attr->gstate->char_space * numchars) + dch;
+ attr->gstate->char_space = 0;
} else {
- sp += ch;
+ dsp += dch;
}
- } else if (ch && numchars)
- char_space += ch / numchars;
-
- if (sp && numspaces)
- word_space += sp / numspaces;
-
- if (attr->gstate->writing_mode == HPDF_WMODE_VERTICAL) {
- char_space *= -1;
- word_space *= -1;
+ } else if (dch && numchars) {
+ attr->gstate->char_space += dch / numchars;
}
- rw = right - left;
- } else if (remove_tatweel && numtatweels) {
- HPDF_Font_SetTatweelCount (font, 0, numtatweels, numchars);
- }
-
- if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
- if (!justify && HPDF_Font_IsRtL(font)) { /* align right. */
- TextPos_AbsToRel (attr->text_matrix,
- right - rw, top, &x, &y);
- if (pos_initialized)
- y = 0;
- if ((ret = HPDF_Page_MoveTextPos (page, x, y))
- != HPDF_OK)
- return ret;
- pos_for_rtl = HPDF_TRUE;
- pos_initialized = HPDF_TRUE;
- } else { /* align left */
- if (!pos_initialized || pos_for_rtl) {
- TextPos_AbsToRel (attr->text_matrix,
- left, top, &x, &y);
- if (pos_for_rtl)
- y = 0;
- if ((ret = HPDF_Page_MoveTextPos (page, x, y))
- != HPDF_OK)
- return ret;
- pos_for_rtl = HPDF_FALSE;
- pos_initialized = HPDF_TRUE;
- }
+ if (dsp && tlw->numspaces) {
+ attr->gstate->word_space += dsp / tlw->numspaces;
}
- } else { /* ignore RtL in vertical writing mode */
- TextPos_AbsToRel (attr->text_matrix, top, -left, &x, &y);
- if (pos_initialized)
- x = -text_leading;
- if ((ret = HPDF_Page_MoveTextPos (page, x, y)) != HPDF_OK)
- return ret;
- pos_initialized = HPDF_TRUE;
}
- pbuf = buf;
- pbuf = HPDF_FToA (pbuf, word_space, eptr);
- *pbuf++ = ' ';
- pbuf = HPDF_FToA (pbuf, char_space, eptr);
- *pbuf++ = ' ';
- *pbuf = 0;
- pbuf = buf;
-
- break;
-
- default:
- if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
- if (!pos_initialized) {
- TextPos_AbsToRel (attr->text_matrix, left, top, &x, &y);
- if ((ret = HPDF_Page_MoveTextPos (page, x, y))
- != HPDF_OK)
- return ret;
- pos_initialized = HPDF_TRUE;
- }
- } else {
- TextPos_AbsToRel (attr->text_matrix, top, -left, &x, &y);
- if (pos_initialized)
- x = -text_leading;
- if ((ret = HPDF_Page_MoveTextPos (page, x, y)) != HPDF_OK)
- return ret;
- pos_initialized = HPDF_TRUE;
- }
break;
}
+ if (!justify && remove_tatweel && tlw->numtatweels)
+ HPDF_Font_SetTatweelCount (font, 0,
+ tlw->numtatweels, tlw->numchars);
- if ((ret = HPDF_Font_ConvertText (font, 0, ptr, tmp_len))
+ if ((ret = HPDF_Font_ConvertText (font, 0, ptr, tlw->numbytes))
!= HPDF_OK)
- return ret;
+ goto END;
- if (InternalWriteText (page, rw, pbuf, operator) != HPDF_OK)
- return HPDF_CheckError (page->error);
-
- if (num_rest <= 0 || ucs4 == 0x0C)
- break;
+ switch (align) {
+ case HPDF_TALIGN_RIGHT:
+ if ((ret = MoveTextPosAbs (page, left + drw,
+ top, HPDF_TRUE, pos_initialized)) != HPDF_OK)
+ goto END;
+ pos_initialized = HPDF_TRUE;
+ break;
- if (attr->gstate->writing_mode == HPDF_WMODE_HORIZONTAL) {
- if (attr->text_pos.y - text_leading < bottom) {
- is_insufficient_space = HPDF_TRUE;
+ case HPDF_TALIGN_CENTER:
+ if ((ret = MoveTextPosAbs (page, left + (drw / 2),
+ top, HPDF_TRUE, pos_initialized)) != HPDF_OK)
+ goto END;
+ pos_initialized = HPDF_TRUE;
break;
- }
- } else if (0 < text_leading) {
- if (attr->text_pos.x - text_leading < bottom) {
- is_insufficient_space = HPDF_TRUE;
+
+ case HPDF_TALIGN_JUSTIFY_ALL:
+ case HPDF_TALIGN_STRETCH_ALL:
+ case HPDF_TALIGN_JUSTIFY:
+ case HPDF_TALIGN_STRETCH:
+ if (!justify && HPDF_Font_IsRtL(font)) { /* align right. */
+ if ((ret = MoveTextPosAbs (page, left + drw,
+ top, HPDF_TRUE, pos_initialized)) != HPDF_OK)
+ goto END;
+ pos_for_rtl = HPDF_TRUE;
+ pos_initialized = HPDF_TRUE;
+ } else { /* align left */
+ if (!pos_initialized || pos_for_rtl) {
+ if ((ret = MoveTextPosAbs (page, left,
+ top, HPDF_TRUE, pos_initialized)) != HPDF_OK)
+ goto END;
+ pos_for_rtl = HPDF_FALSE;
+ pos_initialized = HPDF_TRUE;
+ }
+ }
break;
- }
- } else {
- if (bottom < attr->text_pos.x - text_leading) {
- is_insufficient_space = HPDF_TRUE;
+
+ default:
+ if (!pos_initialized) {
+ if ((ret = MoveTextPosAbs (page, left,
+ top, HPDF_TRUE, HPDF_FALSE)) != HPDF_OK)
+ goto END;
+ pos_initialized = HPDF_TRUE;
+ }
break;
- }
}
- if (line_break && bidi_each_paragraph)
+ if ((ret = InternalWriteText (page, HPDF_FALSE, oper)) != HPDF_OK)
+ goto END;
+
+ if (line_break && bidi_each_paragraph && line + 1 < lines)
HPDF_Font_CheckBiDi (font, HPDF_TRUE);
- ptr += line_len;
+ ptr += tlw->linebytes;
}
- if (word_space != attr->gstate->word_space)
- if ((ret = HPDF_Page_SetWordSpace (page, attr->gstate->word_space))
- != HPDF_OK)
+ END:
+ HPDF_FreeMem (page->mmgr, text_line_width);
+
+ if (ret != HPDF_OK)
+ return ret;
+
+ if (attr->gstate->word_space != save_word_space) {
+ attr->gstate->word_space = save_word_space;
+ if ((ret = SetWordSpace (page, attr->gstate->word_space)) != HPDF_OK)
return ret;
+ }
- if (char_space != attr->gstate->char_space)
- if ((ret = HPDF_Page_SetCharSpace (page, attr->gstate->char_space))
- != HPDF_OK)
+ if (attr->gstate->char_space != save_char_space) {
+ attr->gstate->char_space = save_char_space;
+ if ((ret = SetCharSpace (page, attr->gstate->char_space)) != HPDF_OK)
return ret;
+ }
- if (save_text_leading != attr->gstate->text_leading)
- if ((ret = HPDF_Page_SetTextLeading (page, save_text_leading))
+ if (attr->gstate->text_leading != save_leading)
+ if ((ret = HPDF_Page_SetTextLeading (page, save_leading))
!= HPDF_OK)
return ret;
- if (is_insufficient_space)
+ if (num_rest)
return HPDF_PAGE_INSUFFICIENT_SPACE;
else
return HPDF_OK;
@@ -2856,7 +3223,7 @@ HPDF_Page_SetSlideShow (HPDF_Page page,
HPDF_TransitionStyle type,
HPDF_REAL disp_time,
HPDF_REAL trans_time)
- {
+{
HPDF_STATUS ret = HPDF_OK;
HPDF_Dict dict;
@@ -3002,7 +3369,7 @@ HPDF_Page_New_Content_Stream (HPDF_Page page,
/* check if there is already an array of contents */
contents_array = (HPDF_Array) HPDF_Dict_GetItem(page,"Contents", HPDF_OCLASS_ARRAY);
- if (!contents_array) {
+ if (!contents_array) {
HPDF_Error_Reset (page->error);
/* no contents_array already -- create one
and replace current single contents item */
@@ -3023,7 +3390,7 @@ HPDF_Page_New_Content_Stream (HPDF_Page page,
ret += HPDF_Array_Add (contents_array,attr->contents);
- /* return the value of the new stream, so that
+ /* return the value of the new stream, so that
the application can use it as a shared contents stream */
if (ret == HPDF_OK && new_stream != NULL)
*new_stream = attr->contents;
@@ -3051,7 +3418,7 @@ HPDF_Page_Insert_Shared_Content_Stream (HPDF_Page page,
/* check if there is already an array of contents */
contents_array = (HPDF_Array) HPDF_Dict_GetItem(page,"Contents", HPDF_OCLASS_ARRAY);
- if (!contents_array) {
+ if (!contents_array) {
HPDF_PageAttr attr;
HPDF_Error_Reset (page->error);
/* no contents_array already -- create one
diff --git a/src/hpdf_pages.c b/src/hpdf_pages.c
index 9f833da..4641337 100644
--- a/src/hpdf_pages.c
+++ b/src/hpdf_pages.c
@@ -715,6 +715,7 @@ HPDF_Page_TextWidth (HPDF_Page page,
HPDF_TextWidth tw;
HPDF_REAL ret = 0;
HPDF_UINT len = 0;
+ HPDF_REAL char_space, word_space;
HPDF_PTRACE((" HPDF_Page_TextWidth\n"));
@@ -730,17 +731,20 @@ HPDF_Page_TextWidth (HPDF_Page page,
return 0;
}
- if (text) {
+ if (text)
len = HPDF_Font_StrLen(font, text, HPDF_LIMIT_MAX_STRING_LEN + 1);
- if (len == 0)
- return 0;
- }
tw = HPDF_Font_TextWidth (font, (const HPDF_BYTE *)text, len);
- ret += attr->gstate->word_space * tw.numspace;
+ char_space = attr->gstate->char_space;
+ word_space = attr->gstate->word_space;
+ if (attr->gstate->writing_mode == HPDF_WMODE_VERTICAL) {
+ char_space = -char_space;
+ word_space = -word_space;
+ }
+ ret += tw.numchars * char_space;
+ ret += tw.numspace * word_space;
ret += tw.width * attr->gstate->font_size / 1000;
- ret += attr->gstate->char_space * tw.numchars;
HPDF_CheckError (page->error);
@@ -755,23 +759,28 @@ HPDF_Page_MeasureText (HPDF_Page page,
HPDF_INT options,
HPDF_REAL *real_width)
{
+ HPDF_TextLineWidth tlw;
+ HPDF_UINT lines;
+
HPDF_PTRACE((" HPDF_Page_MeasureText\n"));
- return HPDF_Page_MeasureTextEx (page, text, width, options, real_width,
- NULL, NULL, NULL, NULL);
+ lines = HPDF_Page_MeasureTextLines (page, text, width, options, &tlw, 1);
+ if (!lines)
+ return 0;
+
+ if (real_width)
+ *real_width = tlw.width;
+ return tlw.linebytes;
}
HPDF_EXPORT(HPDF_UINT)
-HPDF_Page_MeasureTextEx (HPDF_Page page,
- const char *text,
- HPDF_REAL width,
- HPDF_INT options,
- HPDF_REAL *real_width,
- HPDF_UINT *numbytes,
- HPDF_UINT *numchars,
- HPDF_UINT *numspaces,
- HPDF_UINT *numtatweels)
+HPDF_Page_MeasureTextLines (HPDF_Page page,
+ const char *text,
+ HPDF_REAL line_width,
+ HPDF_INT options,
+ HPDF_TextLineWidth *width,
+ HPDF_UINT max_lines)
{
HPDF_PageAttr attr;
HPDF_Font font;
@@ -781,7 +790,7 @@ HPDF_Page_MeasureTextEx (HPDF_Page page,
HPDF_PTRACE((" HPDF_Page_MeasureTextEx\n"));
- if (!HPDF_Page_Validate (page) || !text)
+ if (!HPDF_Page_Validate (page) || !text || !width)
return 0;
attr = (HPDF_PageAttr )page->attr;
@@ -800,12 +809,12 @@ HPDF_Page_MeasureTextEx (HPDF_Page page,
char_space = attr->gstate->char_space;
word_space = attr->gstate->word_space;
if (attr->gstate->writing_mode == HPDF_WMODE_VERTICAL) {
- char_space *= -1;
- word_space *= -1;
+ char_space = -char_space;
+ word_space = -word_space;
}
- ret = HPDF_Font_MeasureTextEx (font, (const HPDF_BYTE *)text, len, width,
- attr->gstate->font_size, char_space, word_space, options,
- real_width, numbytes, numchars, numspaces, numtatweels);
+ ret = HPDF_Font_MeasureTextLines (font, (const HPDF_BYTE *)text, len,
+ line_width, attr->gstate->font_size, char_space, word_space,
+ options, width, max_lines);
HPDF_CheckError (page->error);
@@ -2037,3 +2046,25 @@ HPDF_Page_SetJustifyRatio (HPDF_Page page,
return HPDF_OK;
}
+
+
+HPDF_EXPORT(HPDF_STATUS)
+HPDF_Page_InterlinearAnnotationRatio (HPDF_Page page,
+ HPDF_REAL ratio)
+{
+ HPDF_PageAttr attr;
+
+ HPDF_PTRACE((" HPDF_Page_InterlinearAnnotationRatio\n"));
+
+ if (!HPDF_Page_Validate (page))
+ return HPDF_INVALID_PAGE;
+
+ attr = (HPDF_PageAttr)page->attr;
+
+ if (ratio <= 0)
+ return HPDF_RaiseError (page->error, HPDF_INVALID_PARAMETER, 0);
+
+ attr->gstate->ia_font_size_ratio = ratio;
+
+ return HPDF_OK;
+}