Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(404)

Side by Side Diff: core/src/fxge/ge/fx_ge_text.cpp

Issue 453133004: clang-format all code (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "../../../include/fxge/fx_ge.h" 7 #include "../../../include/fxge/fx_ge.h"
8 #include "../../../include/fxge/fx_freetype.h" 8 #include "../../../include/fxge/fx_freetype.h"
9 #include "../../../include/fxcodec/fx_codec.h" 9 #include "../../../include/fxcodec/fx_codec.h"
10 #include "text_int.h" 10 #include "text_int.h"
11 #undef FX_GAMMA 11 #undef FX_GAMMA
12 #undef FX_GAMMA_INVERSE 12 #undef FX_GAMMA_INVERSE
13 #define FX_GAMMA(value)»» » (value) 13 #define FX_GAMMA(value) (value)
14 #define FX_GAMMA_INVERSE(value)»(value) 14 #define FX_GAMMA_INVERSE(value) (value)
15 FX_RECT FXGE_GetGlyphsBBox(FXTEXT_GLYPHPOS* pGlyphAndPos, int nChars, int anti_a lias, FX_FLOAT retinaScaleX, FX_FLOAT retinaScaleY) 15 FX_RECT FXGE_GetGlyphsBBox(FXTEXT_GLYPHPOS* pGlyphAndPos,
16 { 16 int nChars,
17 FX_RECT rect(0, 0, 0, 0); 17 int anti_alias,
18 FX_BOOL bStarted = FALSE; 18 FX_FLOAT retinaScaleX,
19 for (int iChar = 0; iChar < nChars; iChar ++) { 19 FX_FLOAT retinaScaleY) {
20 FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar]; 20 FX_RECT rect(0, 0, 0, 0);
21 const CFX_GlyphBitmap* pGlyph = glyph.m_pGlyph; 21 FX_BOOL bStarted = FALSE;
22 if (pGlyph == NULL) { 22 for (int iChar = 0; iChar < nChars; iChar++) {
23 continue; 23 FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
24 } 24 const CFX_GlyphBitmap* pGlyph = glyph.m_pGlyph;
25 int char_left = glyph.m_OriginX + pGlyph->m_Left; 25 if (pGlyph == NULL) {
26 int char_width = (int)(pGlyph->m_Bitmap.GetWidth() / retinaScaleX); 26 continue;
27 if (anti_alias == FXFT_RENDER_MODE_LCD) { 27 }
28 char_width /= 3; 28 int char_left = glyph.m_OriginX + pGlyph->m_Left;
29 } 29 int char_width = (int)(pGlyph->m_Bitmap.GetWidth() / retinaScaleX);
30 int char_right = char_left + char_width; 30 if (anti_alias == FXFT_RENDER_MODE_LCD) {
31 int char_top = glyph.m_OriginY - pGlyph->m_Top; 31 char_width /= 3;
32 int char_bottom = char_top + (int)(pGlyph->m_Bitmap.GetHeight() / retina ScaleY); 32 }
33 if (!bStarted) { 33 int char_right = char_left + char_width;
34 rect.left = char_left; 34 int char_top = glyph.m_OriginY - pGlyph->m_Top;
35 rect.right = char_right; 35 int char_bottom =
36 rect.top = char_top; 36 char_top + (int)(pGlyph->m_Bitmap.GetHeight() / retinaScaleY);
37 rect.bottom = char_bottom; 37 if (!bStarted) {
38 bStarted = TRUE; 38 rect.left = char_left;
39 } else { 39 rect.right = char_right;
40 if (rect.left > char_left) { 40 rect.top = char_top;
41 rect.left = char_left; 41 rect.bottom = char_bottom;
42 } 42 bStarted = TRUE;
43 if (rect.right < char_right) { 43 } else {
44 rect.right = char_right; 44 if (rect.left > char_left) {
45 } 45 rect.left = char_left;
46 if (rect.top > char_top) { 46 }
47 rect.top = char_top; 47 if (rect.right < char_right) {
48 } 48 rect.right = char_right;
49 if (rect.bottom < char_bottom) { 49 }
50 rect.bottom = char_bottom; 50 if (rect.top > char_top) {
51 } 51 rect.top = char_top;
52 } 52 }
53 } 53 if (rect.bottom < char_bottom) {
54 return rect; 54 rect.bottom = char_bottom;
55 } 55 }
56 static void _AdjustGlyphSpace(FXTEXT_GLYPHPOS* pGlyphAndPos, int nChars) 56 }
57 { 57 }
58 ASSERT(nChars > 1); 58 return rect;
59 FX_BOOL bVertical = FALSE; 59 }
60 if (pGlyphAndPos[nChars - 1].m_OriginX == pGlyphAndPos[0].m_OriginX) { 60 static void _AdjustGlyphSpace(FXTEXT_GLYPHPOS* pGlyphAndPos, int nChars) {
61 bVertical = TRUE; 61 ASSERT(nChars > 1);
62 } else if (pGlyphAndPos[nChars - 1].m_OriginY != pGlyphAndPos[0].m_OriginY) { 62 FX_BOOL bVertical = FALSE;
63 return; 63 if (pGlyphAndPos[nChars - 1].m_OriginX == pGlyphAndPos[0].m_OriginX) {
64 } 64 bVertical = TRUE;
65 int i = nChars - 1; 65 } else if (pGlyphAndPos[nChars - 1].m_OriginY != pGlyphAndPos[0].m_OriginY) {
66 int* next_origin = bVertical ? &pGlyphAndPos[i].m_OriginY : &pGlyphAndPos[i] .m_OriginX; 66 return;
67 FX_FLOAT next_origin_f = bVertical ? pGlyphAndPos[i].m_fOriginY : pGlyphAndP os[i].m_fOriginX; 67 }
68 for (i --; i > 0; i --) { 68 int i = nChars - 1;
69 int* this_origin = bVertical ? &pGlyphAndPos[i].m_OriginY : &pGlyphAndPo s[i].m_OriginX; 69 int* next_origin =
70 FX_FLOAT this_origin_f = bVertical ? pGlyphAndPos[i].m_fOriginY : pGlyph AndPos[i].m_fOriginX; 70 bVertical ? &pGlyphAndPos[i].m_OriginY : &pGlyphAndPos[i].m_OriginX;
71 int space = (*next_origin) - (*this_origin); 71 FX_FLOAT next_origin_f =
72 FX_FLOAT space_f = next_origin_f - this_origin_f; 72 bVertical ? pGlyphAndPos[i].m_fOriginY : pGlyphAndPos[i].m_fOriginX;
73 FX_FLOAT error = (FX_FLOAT)(FXSYS_fabs(space_f) - FXSYS_fabs((FX_FLOAT)( space))); 73 for (i--; i > 0; i--) {
74 if (error > 0.5f) { 74 int* this_origin =
75 *this_origin += space > 0 ? -1 : 1; 75 bVertical ? &pGlyphAndPos[i].m_OriginY : &pGlyphAndPos[i].m_OriginX;
76 } 76 FX_FLOAT this_origin_f =
77 next_origin = this_origin; 77 bVertical ? pGlyphAndPos[i].m_fOriginY : pGlyphAndPos[i].m_fOriginX;
78 next_origin_f = this_origin_f; 78 int space = (*next_origin) - (*this_origin);
79 } 79 FX_FLOAT space_f = next_origin_f - this_origin_f;
80 FX_FLOAT error =
81 (FX_FLOAT)(FXSYS_fabs(space_f) - FXSYS_fabs((FX_FLOAT)(space)));
82 if (error > 0.5f) {
83 *this_origin += space > 0 ? -1 : 1;
84 }
85 next_origin = this_origin;
86 next_origin_f = this_origin_f;
87 }
80 } 88 }
81 static const FX_BYTE g_TextGammaAdjust[256] = { 89 static const FX_BYTE g_TextGammaAdjust[256] = {
82 0, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18, 19, 90 0, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18,
83 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 38, 91 19, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35,
84 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, 52, 53, 54, 55, 92 36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, 52,
85 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, 93 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
86 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 94 68, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
87 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 95 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
88 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 1 20, 96 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
89 121, 122, 123, 124, 125, 126, 127, 128, 129, 129, 130, 131, 132, 133, 134, 1 35, 97 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
90 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 1 51, 98 129, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
91 152, 153, 154, 155, 156, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 1 66, 99 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 156,
92 167, 168, 169, 170, 171, 172, 173, 174, 174, 175, 176, 177, 178, 179, 180, 1 81, 100 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171,
93 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 193, 194, 195, 1 96, 101 172, 173, 174, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185,
94 197, 198, 199, 200, 201, 202, 203, 204, 204, 205, 206, 207, 208, 209, 210, 2 11, 102 186, 187, 188, 189, 190, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
95 212, 213, 214, 215, 216, 217, 217, 218, 219, 220, 221, 222, 223, 224, 225, 2 26, 103 200, 201, 202, 203, 204, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
96 227, 228, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 239, 2 40, 104 214, 215, 216, 217, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
97 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 250, 251, 252, 253, 254, 2 55, 105 228, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 239, 240,
106 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 250, 251, 252, 253, 254,
107 255,
98 }; 108 };
99 #define ADJUST_ALPHA(background, foreground, src_alpha, text_flags, a) \ 109 #define ADJUST_ALPHA(background, foreground, src_alpha, text_flags, a) \
100 src_alpha = g_TextGammaAdjust[(FX_BYTE)src_alpha]; 110 src_alpha = g_TextGammaAdjust[(FX_BYTE)src_alpha];
101 void _Color2Argb(FX_ARGB& argb, FX_DWORD color, int alpha_flag, void* pIccTransf orm) 111 void _Color2Argb(FX_ARGB& argb,
102 { 112 FX_DWORD color,
103 if (pIccTransform == NULL && !FXGETFLAG_COLORTYPE(alpha_flag)) { 113 int alpha_flag,
104 argb = color; 114 void* pIccTransform) {
105 return; 115 if (pIccTransform == NULL && !FXGETFLAG_COLORTYPE(alpha_flag)) {
106 } 116 argb = color;
107 if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodec Module()->GetIccModule()) { 117 return;
108 pIccTransform = NULL; 118 }
109 } 119 if (!CFX_GEModule::Get()->GetCodecModule() ||
110 FX_BYTE bgra[4]; 120 !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
111 if (pIccTransform) { 121 pIccTransform = NULL;
112 ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->Ge tIccModule(); 122 }
113 color = FXGETFLAG_COLORTYPE(alpha_flag) ? FXCMYK_TODIB(color) : FXARGB_T ODIB(color); 123 FX_BYTE bgra[4];
114 pIccModule->TranslateScanline(pIccTransform, bgra, (FX_LPCBYTE)&color, 1 ); 124 if (pIccTransform) {
115 bgra[3] = FXGETFLAG_COLORTYPE(alpha_flag) ? 125 ICodec_IccModule* pIccModule =
116 (alpha_flag >> 24) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXGETF LAG_ALPHA_STROKE(alpha_flag) : 126 CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
117 FXARGB_A(color); 127 color = FXGETFLAG_COLORTYPE(alpha_flag) ? FXCMYK_TODIB(color)
118 argb = FXARGB_MAKE(bgra[3], bgra[2], bgra[1], bgra[0]); 128 : FXARGB_TODIB(color);
119 return; 129 pIccModule->TranslateScanline(pIccTransform, bgra, (FX_LPCBYTE)&color, 1);
120 } 130 bgra[3] = FXGETFLAG_COLORTYPE(alpha_flag)
121 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), 131 ? (alpha_flag >> 24) ? FXGETFLAG_ALPHA_FILL(alpha_flag)
122 FXSYS_GetYValue(color), FXSYS_GetKValue(color), 132 : FXGETFLAG_ALPHA_STROKE(alpha_flag)
123 bgra[2], bgra[1], bgra[0]); 133 : FXARGB_A(color);
124 bgra[3] = (alpha_flag >> 24) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXGETFLAG_ ALPHA_STROKE(alpha_flag);
125 argb = FXARGB_MAKE(bgra[3], bgra[2], bgra[1], bgra[0]); 134 argb = FXARGB_MAKE(bgra[3], bgra[2], bgra[1], bgra[0]);
126 } 135 return;
127 FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars, const FXTEXT_CHARPOS* pChar Pos, 136 }
128 CFX_Font* pFont, CFX_FontCache* pCache, 137 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color),
129 FX_FLOAT font_size, const CFX_AffineMatrix* pText2Device, 138 FXSYS_GetMValue(color),
130 FX_DWORD fill_color, FX_DWORD text_flags, 139 FXSYS_GetYValue(color),
131 int alpha_flag, void* pIccTransform) 140 FXSYS_GetKValue(color),
132 { 141 bgra[2],
133 int nativetext_flags = text_flags; 142 bgra[1],
134 if (m_DeviceClass != FXDC_DISPLAY) { 143 bgra[0]);
135 if (!(text_flags & FXTEXT_PRINTGRAPHICTEXT)) { 144 bgra[3] = (alpha_flag >> 24) ? FXGETFLAG_ALPHA_FILL(alpha_flag)
136 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 145 : FXGETFLAG_ALPHA_STROKE(alpha_flag);
137 if (!(text_flags & FXFONT_CIDFONT) && pFont->GetPsName().Find(CFX_Wi deString::FromLocal("+ZJHL")) == -1) 146 argb = FXARGB_MAKE(bgra[3], bgra[2], bgra[1], bgra[0]);
147 }
148 FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars,
149 const FXTEXT_CHARPOS* pCharPos,
150 CFX_Font* pFont,
151 CFX_FontCache* pCache,
152 FX_FLOAT font_size,
153 const CFX_AffineMatrix* pText2Device,
154 FX_DWORD fill_color,
155 FX_DWORD text_flags,
156 int alpha_flag,
157 void* pIccTransform) {
158 int nativetext_flags = text_flags;
159 if (m_DeviceClass != FXDC_DISPLAY) {
160 if (!(text_flags & FXTEXT_PRINTGRAPHICTEXT)) {
161 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
162 if (!(text_flags & FXFONT_CIDFONT) &&
163 pFont->GetPsName().Find(CFX_WideString::FromLocal("+ZJHL")) == -1)
138 #ifdef FOXIT_CHROME_BUILD 164 #ifdef FOXIT_CHROME_BUILD
139 if (pFont->GetPsName() != CFX_WideString::FromLocal("CNAAJI+cmex 10")) 165 if (pFont->GetPsName() != CFX_WideString::FromLocal("CNAAJI+cmex10"))
140 #endif 166 #endif
141 #endif 167 #endif
142 if (m_pDeviceDriver->DrawDeviceText(nChars, pCharPos, pFont, pCache, pText2Device, font_size, fill_color, alpha_flag, pIccTransform)) { 168 if (m_pDeviceDriver->DrawDeviceText(nChars,
143 return TRUE; 169 pCharPos,
144 } 170 pFont,
145 } 171 pCache,
146 int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha _flag) : FXARGB_A(fill_color); 172 pText2Device,
147 if (alpha < 255) { 173 font_size,
148 return FALSE; 174 fill_color,
149 } 175 alpha_flag,
150 } else if (!(text_flags & FXTEXT_NO_NATIVETEXT)) { 176 pIccTransform)) {
151 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 177 return TRUE;
152 if (!(text_flags & FXFONT_CIDFONT)) 178 }
179 }
180 int alpha = FXGETFLAG_COLORTYPE(alpha_flag)
181 ? FXGETFLAG_ALPHA_FILL(alpha_flag)
182 : FXARGB_A(fill_color);
183 if (alpha < 255) {
184 return FALSE;
185 }
186 } else if (!(text_flags & FXTEXT_NO_NATIVETEXT)) {
187 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
188 if (!(text_flags & FXFONT_CIDFONT))
153 #ifdef FOXIT_CHROME_BUILD 189 #ifdef FOXIT_CHROME_BUILD
154 if (pFont->GetPsName() != CFX_WideString::FromLocal("CNAAJI+cmex10") ) 190 if (pFont->GetPsName() != CFX_WideString::FromLocal("CNAAJI+cmex10"))
155 #endif 191 #endif
156 #endif 192 #endif
157 if (m_pDeviceDriver->DrawDeviceText(nChars, pCharPos, pFont, pCa che, pText2Device, font_size, fill_color, alpha_flag, pIccTransform)) { 193 if (m_pDeviceDriver->DrawDeviceText(nChars,
158 return TRUE; 194 pCharPos,
159 } 195 pFont,
160 } 196 pCache,
161 CFX_AffineMatrix char2device, deviceCtm, text2Device; 197 pText2Device,
162 if (pText2Device) { 198 font_size,
163 char2device = *pText2Device; 199 fill_color,
164 text2Device = *pText2Device; 200 alpha_flag,
165 } 201 pIccTransform)) {
166 char2device.Scale(font_size, -font_size); 202 return TRUE;
167 if (FXSYS_fabs(char2device.a) + FXSYS_fabs(char2device.b) > 50 * 1.0f ||
168 ((m_DeviceClass == FXDC_PRINTER && !m_pDeviceDriver->IsPSPrintDriver ())
169 && !(text_flags & FXTEXT_PRINTIMAGETEXT))) {
170 if (pFont->GetFace() != NULL || (pFont->GetSubstFont()->m_SubstFlags & F XFONT_SUBST_GLYPHPATH)) {
171 int nPathFlags = (text_flags & FXTEXT_NOSMOOTH) == 0 ? 0 : FXFILL_NO PATHSMOOTH;
172 return DrawTextPath(nChars, pCharPos, pFont, pCache, font_size, pTex t2Device, NULL, NULL, fill_color, 0, NULL, nPathFlags, alpha_flag, pIccTransform );
173 } 203 }
174 } 204 }
175 int anti_alias = FXFT_RENDER_MODE_MONO; 205 CFX_AffineMatrix char2device, deviceCtm, text2Device;
176 FX_BOOL bNormal = FALSE; 206 if (pText2Device) {
177 if ((text_flags & FXTEXT_NOSMOOTH) == 0) { 207 char2device = *pText2Device;
178 if (m_DeviceClass == FXDC_DISPLAY && m_bpp > 1) { 208 text2Device = *pText2Device;
179 FX_BOOL bClearType; 209 }
180 if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlag s & FXFONT_SUBST_CLEARTYPE)) { 210 char2device.Scale(font_size, -font_size);
181 bClearType = FALSE; 211 if (FXSYS_fabs(char2device.a) + FXSYS_fabs(char2device.b) > 50 * 1.0f ||
182 } else { 212 ((m_DeviceClass == FXDC_PRINTER && !m_pDeviceDriver->IsPSPrintDriver()) &&
183 bClearType = text_flags & FXTEXT_CLEARTYPE; 213 !(text_flags & FXTEXT_PRINTIMAGETEXT))) {
184 } 214 if (pFont->GetFace() != NULL ||
185 if ((m_RenderCaps & (FXRC_ALPHA_OUTPUT | FXRC_CMYK_OUTPUT))) { 215 (pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) {
186 anti_alias = FXFT_RENDER_MODE_LCD; 216 int nPathFlags =
187 bNormal = TRUE; 217 (text_flags & FXTEXT_NOSMOOTH) == 0 ? 0 : FXFILL_NOPATHSMOOTH;
188 } else if (m_bpp < 16) { 218 return DrawTextPath(nChars,
189 anti_alias = FXFT_RENDER_MODE_NORMAL; 219 pCharPos,
190 } else { 220 pFont,
191 if (bClearType == FALSE) { 221 pCache,
192 anti_alias = FXFT_RENDER_MODE_LCD; 222 font_size,
193 bNormal = TRUE; 223 pText2Device,
194 } else { 224 NULL,
195 anti_alias = FXFT_RENDER_MODE_LCD; 225 NULL,
196 } 226 fill_color,
197 } 227 0,
228 NULL,
229 nPathFlags,
230 alpha_flag,
231 pIccTransform);
232 }
233 }
234 int anti_alias = FXFT_RENDER_MODE_MONO;
235 FX_BOOL bNormal = FALSE;
236 if ((text_flags & FXTEXT_NOSMOOTH) == 0) {
237 if (m_DeviceClass == FXDC_DISPLAY && m_bpp > 1) {
238 FX_BOOL bClearType;
239 if (pFont->GetFace() == NULL &&
240 !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_CLEARTYPE)) {
241 bClearType = FALSE;
242 } else {
243 bClearType = text_flags & FXTEXT_CLEARTYPE;
244 }
245 if ((m_RenderCaps & (FXRC_ALPHA_OUTPUT | FXRC_CMYK_OUTPUT))) {
246 anti_alias = FXFT_RENDER_MODE_LCD;
247 bNormal = TRUE;
248 } else if (m_bpp < 16) {
249 anti_alias = FXFT_RENDER_MODE_NORMAL;
250 } else {
251 if (bClearType == FALSE) {
252 anti_alias = FXFT_RENDER_MODE_LCD;
253 bNormal = TRUE;
254 } else {
255 anti_alias = FXFT_RENDER_MODE_LCD;
198 } 256 }
199 } 257 }
200 if (pCache == NULL) { 258 }
201 pCache = CFX_GEModule::Get()->GetFontCache(); 259 }
202 } 260 if (pCache == NULL) {
203 CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont); 261 pCache = CFX_GEModule::Get()->GetFontCache();
204 FX_FONTCACHE_DEFINE(pCache, pFont); 262 }
205 FXTEXT_GLYPHPOS* pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, nChars); 263 CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont);
206 if (!pGlyphAndPos) { 264 FX_FONTCACHE_DEFINE(pCache, pFont);
207 return FALSE; 265 FXTEXT_GLYPHPOS* pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, nChars);
208 } 266 if (!pGlyphAndPos) {
209 int iChar; 267 return FALSE;
210 deviceCtm = char2device; 268 }
211 CFX_AffineMatrix matrixCTM = GetCTM(); 269 int iChar;
212 FX_FLOAT scale_x = FXSYS_fabs(matrixCTM.a); 270 deviceCtm = char2device;
213 FX_FLOAT scale_y = FXSYS_fabs(matrixCTM.d); 271 CFX_AffineMatrix matrixCTM = GetCTM();
214 deviceCtm.Concat(scale_x, 0, 0, scale_y, 0, 0); 272 FX_FLOAT scale_x = FXSYS_fabs(matrixCTM.a);
215 text2Device.Concat(scale_x, 0, 0, scale_y, 0, 0); 273 FX_FLOAT scale_y = FXSYS_fabs(matrixCTM.d);
216 for (iChar = 0; iChar < nChars; iChar ++) { 274 deviceCtm.Concat(scale_x, 0, 0, scale_y, 0, 0);
217 FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar]; 275 text2Device.Concat(scale_x, 0, 0, scale_y, 0, 0);
218 const FXTEXT_CHARPOS& charpos = pCharPos[iChar]; 276 for (iChar = 0; iChar < nChars; iChar++) {
219 glyph.m_fOriginX = charpos.m_OriginX; 277 FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
220 glyph.m_fOriginY = charpos.m_OriginY; 278 const FXTEXT_CHARPOS& charpos = pCharPos[iChar];
221 text2Device.Transform(glyph.m_fOriginX, glyph.m_fOriginY); 279 glyph.m_fOriginX = charpos.m_OriginX;
222 if (anti_alias < FXFT_RENDER_MODE_LCD) { 280 glyph.m_fOriginY = charpos.m_OriginY;
223 glyph.m_OriginX = FXSYS_round(glyph.m_fOriginX); 281 text2Device.Transform(glyph.m_fOriginX, glyph.m_fOriginY);
224 } else { 282 if (anti_alias < FXFT_RENDER_MODE_LCD) {
225 glyph.m_OriginX = (int)FXSYS_floor(glyph.m_fOriginX); 283 glyph.m_OriginX = FXSYS_round(glyph.m_fOriginX);
226 }
227 glyph.m_OriginY = FXSYS_round(glyph.m_fOriginY);
228 if (charpos.m_bGlyphAdjust) {
229 CFX_AffineMatrix new_matrix(charpos.m_AdjustMatrix[0], charpos.m_Adj ustMatrix[1],
230 charpos.m_AdjustMatrix[2], charpos.m_Adj ustMatrix[3], 0, 0);
231 new_matrix.Concat(deviceCtm);
232 glyph.m_pGlyph = pFaceCache->LoadGlyphBitmap(pFont, charpos.m_GlyphI ndex, charpos.m_bFontStyle, &new_matrix,
233 charpos.m_FontCharWidth, anti_alias, nativetext_fla gs);
234 } else
235 glyph.m_pGlyph = pFaceCache->LoadGlyphBitmap(pFont, charpos.m_GlyphI ndex, charpos.m_bFontStyle, &deviceCtm,
236 charpos.m_FontCharWidth, anti_alias, nativetext_fla gs);
237 }
238 if (anti_alias < FXFT_RENDER_MODE_LCD && nChars > 1) {
239 _AdjustGlyphSpace(pGlyphAndPos, nChars);
240 }
241 FX_RECT bmp_rect1 = FXGE_GetGlyphsBBox(pGlyphAndPos, nChars, anti_alias);
242 if (scale_x > 1 && scale_y > 1) {
243 bmp_rect1.left--;
244 bmp_rect1.top --;
245 bmp_rect1.right ++;
246 bmp_rect1.bottom ++;
247 }
248 FX_RECT bmp_rect(FXSYS_round((FX_FLOAT)(bmp_rect1.left) / scale_x), FXSYS_ro und((FX_FLOAT)(bmp_rect1.top) / scale_y),
249 FXSYS_round((FX_FLOAT)bmp_rect1.right / scale_x), FXSYS_rou nd((FX_FLOAT)bmp_rect1.bottom / scale_y));
250 bmp_rect.Intersect(m_ClipBox);
251 if (bmp_rect.IsEmpty()) {
252 FX_Free(pGlyphAndPos);
253 return TRUE;
254 }
255 int pixel_width = FXSYS_round(bmp_rect.Width() * scale_x);
256 int pixel_height = FXSYS_round(bmp_rect.Height() * scale_y);
257 int pixel_left = FXSYS_round(bmp_rect.left * scale_x);
258 int pixel_top = FXSYS_round(bmp_rect.top * scale_y);
259 if (anti_alias == FXFT_RENDER_MODE_MONO) {
260 CFX_DIBitmap bitmap;
261 if (!bitmap.Create(pixel_width, pixel_height, FXDIB_1bppMask)) {
262 FX_Free(pGlyphAndPos);
263 return FALSE;
264 }
265 bitmap.Clear(0);
266 for (iChar = 0; iChar < nChars; iChar ++) {
267 FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
268 if (glyph.m_pGlyph == NULL) {
269 continue;
270 }
271 const CFX_DIBitmap* pGlyph = &glyph.m_pGlyph->m_Bitmap;
272 bitmap.TransferBitmap(glyph.m_OriginX + glyph.m_pGlyph->m_Left - pix el_left,
273 glyph.m_OriginY - glyph.m_pGlyph->m_Top - pixe l_top,
274 pGlyph->GetWidth(), pGlyph->GetHeight(), pGlyp h, 0, 0);
275 }
276 FX_Free(pGlyphAndPos);
277 return SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color);
278 }
279 CFX_DIBitmap bitmap;
280 if (m_bpp == 8) {
281 if (!bitmap.Create(pixel_width, pixel_height, FXDIB_8bppMask)) {
282 FX_Free(pGlyphAndPos);
283 return FALSE;
284 }
285 } else { 284 } else {
286 if (!CreateCompatibleBitmap(&bitmap, pixel_width, pixel_height)) { 285 glyph.m_OriginX = (int)FXSYS_floor(glyph.m_fOriginX);
287 FX_Free(pGlyphAndPos); 286 }
288 return FALSE; 287 glyph.m_OriginY = FXSYS_round(glyph.m_fOriginY);
289 } 288 if (charpos.m_bGlyphAdjust) {
290 } 289 CFX_AffineMatrix new_matrix(charpos.m_AdjustMatrix[0],
291 if (!bitmap.HasAlpha() && !bitmap.IsAlphaMask()) { 290 charpos.m_AdjustMatrix[1],
292 bitmap.Clear(0xFFFFFFFF); 291 charpos.m_AdjustMatrix[2],
293 if (!GetDIBits(&bitmap, bmp_rect.left, bmp_rect.top)) { 292 charpos.m_AdjustMatrix[3],
294 FX_Free(pGlyphAndPos); 293 0,
295 return FALSE; 294 0);
296 } 295 new_matrix.Concat(deviceCtm);
297 } else { 296 glyph.m_pGlyph = pFaceCache->LoadGlyphBitmap(pFont,
298 bitmap.Clear(0); 297 charpos.m_GlyphIndex,
299 if (bitmap.m_pAlphaMask) { 298 charpos.m_bFontStyle,
300 bitmap.m_pAlphaMask->Clear(0); 299 &new_matrix,
301 } 300 charpos.m_FontCharWidth,
302 } 301 anti_alias,
303 int dest_width = pixel_width; 302 nativetext_flags);
304 FX_LPBYTE dest_buf = bitmap.GetBuffer(); 303 } else
305 int dest_pitch = bitmap.GetPitch(); 304 glyph.m_pGlyph = pFaceCache->LoadGlyphBitmap(pFont,
306 int Bpp = bitmap.GetBPP() / 8; 305 charpos.m_GlyphIndex,
307 int a, r, g, b; 306 charpos.m_bFontStyle,
308 if (anti_alias == FXFT_RENDER_MODE_LCD) { 307 &deviceCtm,
309 _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransfor m); 308 charpos.m_FontCharWidth,
310 ArgbDecode(fill_color, a, r, g, b); 309 anti_alias,
311 r = FX_GAMMA(r); 310 nativetext_flags);
312 g = FX_GAMMA(g); 311 }
313 b = FX_GAMMA(b); 312 if (anti_alias < FXFT_RENDER_MODE_LCD && nChars > 1) {
314 } 313 _AdjustGlyphSpace(pGlyphAndPos, nChars);
315 for (iChar = 0; iChar < nChars; iChar ++) { 314 }
316 FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar]; 315 FX_RECT bmp_rect1 = FXGE_GetGlyphsBBox(pGlyphAndPos, nChars, anti_alias);
317 if (glyph.m_pGlyph == NULL) { 316 if (scale_x > 1 && scale_y > 1) {
318 continue; 317 bmp_rect1.left--;
319 } 318 bmp_rect1.top--;
320 const CFX_DIBitmap* pGlyph = &glyph.m_pGlyph->m_Bitmap; 319 bmp_rect1.right++;
321 int left = glyph.m_OriginX + glyph.m_pGlyph->m_Left - pixel_left; 320 bmp_rect1.bottom++;
322 int top = glyph.m_OriginY - glyph.m_pGlyph->m_Top - pixel_top; 321 }
323 int ncols = pGlyph->GetWidth(); 322 FX_RECT bmp_rect(FXSYS_round((FX_FLOAT)(bmp_rect1.left) / scale_x),
324 int nrows = pGlyph->GetHeight(); 323 FXSYS_round((FX_FLOAT)(bmp_rect1.top) / scale_y),
325 if (anti_alias == FXFT_RENDER_MODE_NORMAL) { 324 FXSYS_round((FX_FLOAT)bmp_rect1.right / scale_x),
326 if (!bitmap.CompositeMask(left, top, ncols, nrows, pGlyph, fill_colo r, 325 FXSYS_round((FX_FLOAT)bmp_rect1.bottom / scale_y));
327 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alp ha_flag, pIccTransform)) { 326 bmp_rect.Intersect(m_ClipBox);
328 FX_Free(pGlyphAndPos); 327 if (bmp_rect.IsEmpty()) {
329 return FALSE;
330 }
331 continue;
332 }
333 FX_BOOL bBGRStripe = text_flags & FXTEXT_BGR_STRIPE;
334 ncols /= 3;
335 int x_subpixel = (int)(glyph.m_fOriginX * 3) % 3;
336 FX_LPBYTE src_buf = pGlyph->GetBuffer();
337 int src_pitch = pGlyph->GetPitch();
338 int start_col = left;
339 if (start_col < 0) {
340 start_col = 0;
341 }
342 int end_col = left + ncols;
343 if (end_col > dest_width) {
344 end_col = dest_width;
345 }
346 if (start_col >= end_col) {
347 continue;
348 }
349 if (bitmap.GetFormat() == FXDIB_Argb) {
350 for (int row = 0; row < nrows; row ++) {
351 int dest_row = row + top;
352 if (dest_row < 0 || dest_row >= bitmap.GetHeight()) {
353 continue;
354 }
355 FX_LPBYTE src_scan = src_buf + row * src_pitch + (start_col - le ft) * 3;
356 FX_LPBYTE dest_scan = dest_buf + dest_row * dest_pitch + (start_ col << 2);
357 if (bBGRStripe) {
358 if (x_subpixel == 0) {
359 for (int col = start_col; col < end_col; col ++) {
360 int src_alpha = src_scan[2];
361 src_alpha = src_alpha * a / 255;
362 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha));
363 src_alpha = src_scan[1];
364 src_alpha = src_alpha * a / 255;
365 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
366 src_alpha = src_scan[0];
367 src_alpha = src_alpha * a / 255;
368 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
369 dest_scan[3] = 255;
370 dest_scan += 4;
371 src_scan += 3;
372 }
373 } else if (x_subpixel == 1) {
374 int src_alpha = src_scan[1];
375 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flag s, a);
376 src_alpha = src_alpha * a / 255;
377 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAM MA(dest_scan[2]), r, src_alpha));
378 src_alpha = src_scan[0];
379 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flag s, a);
380 src_alpha = src_alpha * a / 255;
381 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAM MA(dest_scan[1]), g, src_alpha));
382 if (start_col > left) {
383 src_alpha = src_scan[-1];
384 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
385 src_alpha = src_alpha * a / 255;
386 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
387 }
388 dest_scan[3] = 255;
389 dest_scan += 4;
390 src_scan += 3;
391 for (int col = start_col + 1; col < end_col - 1; col ++) {
392 int src_alpha = src_scan[1];
393 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_ flags, a);
394 src_alpha = src_alpha * a / 255;
395 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha));
396 src_alpha = src_scan[0];
397 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
398 src_alpha = src_alpha * a / 255;
399 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
400 src_alpha = src_scan[-1];
401 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
402 src_alpha = src_alpha * a / 255;
403 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
404 dest_scan[3] = 255;
405 dest_scan += 4;
406 src_scan += 3;
407 }
408 } else {
409 int src_alpha = src_scan[0];
410 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flag s, a);
411 src_alpha = src_alpha * a / 255;
412 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAM MA(dest_scan[2]), r, src_alpha));
413 if (start_col > left) {
414 src_alpha = src_scan[-1];
415 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
416 src_alpha = src_alpha * a / 255;
417 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
418 src_alpha = src_scan[-2];
419 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
420 src_alpha = src_alpha * a / 255;
421 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
422 }
423 dest_scan[3] = 255;
424 dest_scan += 4;
425 src_scan += 3;
426 for (int col = start_col + 1; col < end_col - 1; col ++) {
427 int src_alpha = src_scan[0];
428 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_ flags, a);
429 src_alpha = src_alpha * a / 255;
430 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha));
431 src_alpha = src_scan[-1];
432 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
433 src_alpha = src_alpha * a / 255;
434 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
435 src_alpha = src_scan[-2];
436 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
437 src_alpha = src_alpha * a / 255;
438 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
439 dest_scan[3] = 255;
440 dest_scan += 4;
441 src_scan += 3;
442 }
443 }
444 } else {
445 if (x_subpixel == 0) {
446 for (int col = start_col; col < end_col; col ++) {
447 if (bNormal) {
448 int src_alpha1 = (src_scan[0] + src_scan[1] + sr c_scan[2]) / 3;
449 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, native text_flags, a);
450 src_alpha1 = src_alpha1 * a / 255;
451 FX_BYTE back_alpha = dest_scan[3];
452 if (back_alpha == 0) {
453 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alp ha1, r, g, b));
454 dest_scan += 4;
455 src_scan += 3;
456 continue;
457 }
458 if (src_alpha1 == 0) {
459 dest_scan += 4;
460 src_scan += 3;
461 continue;
462 }
463 FX_BYTE dest_alpha = back_alpha + src_alpha1 - b ack_alpha * src_alpha1 / 255;
464 dest_scan[3] = dest_alpha;
465 int alpha_ratio = src_alpha1 * 255 / dest_alpha;
466 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
467 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
468 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
469 dest_scan += 4;
470 src_scan += 3;
471 continue;
472 }
473 int src_alpha = src_scan[0];
474 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_ flags, a);
475 src_alpha = src_alpha * a / 255;
476 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha));
477 src_alpha = src_scan[1];
478 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
479 src_alpha = src_alpha * a / 255;
480 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
481 src_alpha = src_scan[2];
482 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
483 src_alpha = src_alpha * a / 255;
484 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
485 dest_scan[3] = 255;
486 dest_scan += 4;
487 src_scan += 3;
488 }
489 } else if (x_subpixel == 1) {
490 if (bNormal) {
491 int src_alpha1 = start_col > left ? ((src_scan[-1] + src_scan[0] + src_scan[1]) / 3) : ((src_scan[0] + src_scan[1]) / 3);
492 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext _flags, a);
493 src_alpha1 = src_alpha1 * a / 255;
494 if (src_alpha1 == 0) {
495 dest_scan += 4;
496 src_scan += 3;
497 } else {
498 FX_BYTE back_alpha = dest_scan[3];
499 if (back_alpha == 0) {
500 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alp ha1, r, g, b));
501 } else {
502 FX_BYTE dest_alpha = back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
503 dest_scan[3] = dest_alpha;
504 int alpha_ratio = src_alpha1 * 255 / dest_al pha;
505 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_ MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
506 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_ MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
507 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_ MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
508 }
509 dest_scan += 4;
510 src_scan += 3;
511 }
512 } else {
513 if (start_col > left) {
514 int src_alpha = src_scan[-1];
515 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativet ext_flags, a);
516 src_alpha = src_alpha * a / 255;
517 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[2]), r, src_alpha));
518 }
519 int src_alpha = src_scan[0];
520 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
521 src_alpha = src_alpha * a / 255;
522 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
523 src_alpha = src_scan[1];
524 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
525 src_alpha = src_alpha * a / 255;
526 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
527 dest_scan[3] = 255;
528 dest_scan += 4;
529 src_scan += 3;
530 }
531 for (int col = start_col + 1; col < end_col; col ++) {
532 if (bNormal) {
533 int src_alpha1 = (src_scan[-1] + src_scan[0] + s rc_scan[1]) / 3;
534 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, native text_flags, a);
535 src_alpha1 = src_alpha1 * a / 255;
536 FX_BYTE back_alpha = dest_scan[3];
537 if (back_alpha == 0) {
538 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alp ha1, r, g, b));
539 dest_scan += 4;
540 src_scan += 3;
541 continue;
542 }
543 if (src_alpha1 == 0) {
544 dest_scan += 4;
545 src_scan += 3;
546 continue;
547 }
548 FX_BYTE dest_alpha = back_alpha + src_alpha1 - b ack_alpha * src_alpha1 / 255;
549 dest_scan[3] = dest_alpha;
550 int alpha_ratio = src_alpha1 * 255 / dest_alpha;
551 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
552 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
553 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
554 dest_scan += 4;
555 src_scan += 3;
556 continue;
557 }
558 int src_alpha = src_scan[-1];
559 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_ flags, a);
560 src_alpha = src_alpha * a / 255;
561 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha));
562 src_alpha = src_scan[0];
563 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
564 src_alpha = src_alpha * a / 255;
565 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
566 src_alpha = src_scan[1];
567 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
568 src_alpha = src_alpha * a / 255;
569 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
570 dest_scan[3] = 255;
571 dest_scan += 4;
572 src_scan += 3;
573 }
574 } else {
575 if (bNormal) {
576 int src_alpha1 = start_col > left ? ((src_scan[-2] + src_scan[-1] + src_scan[0]) / 3) : ((src_scan[0]) / 3);
577 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext _flags, a);
578 src_alpha1 = src_alpha1 * a / 255;
579 if (src_alpha1 == 0) {
580 dest_scan += 4;
581 src_scan += 3;
582 } else {
583 FX_BYTE back_alpha = dest_scan[3];
584 if (back_alpha == 0) {
585 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alp ha1, r, g, b));
586 } else {
587 FX_BYTE dest_alpha = back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
588 dest_scan[3] = dest_alpha;
589 int alpha_ratio = src_alpha1 * 255 / dest_al pha;
590 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_ MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
591 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_ MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
592 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_ MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
593 }
594 dest_scan += 4;
595 src_scan += 3;
596 }
597 } else {
598 if (start_col > left) {
599 int src_alpha = src_scan[-2];
600 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativet ext_flags, a);
601 src_alpha = src_alpha * a / 255;
602 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[2]), r, src_alpha));
603 src_alpha = src_scan[-1];
604 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativet ext_flags, a);
605 src_alpha = src_alpha * a / 255;
606 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[1]), g, src_alpha));
607 }
608 int src_alpha = src_scan[0];
609 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
610 src_alpha = src_alpha * a / 255;
611 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
612 dest_scan[3] = 255;
613 dest_scan += 4;
614 src_scan += 3;
615 }
616 for (int col = start_col + 1; col < end_col; col ++) {
617 if (bNormal) {
618 int src_alpha1 = (src_scan[-2] + src_scan[-1] + src_scan[0]) / 3;
619 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, native text_flags, a);
620 src_alpha1 = src_alpha1 * a / 255;
621 FX_BYTE back_alpha = dest_scan[3];
622 if (back_alpha == 0) {
623 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alp ha1, r, g, b));
624 dest_scan += 4;
625 src_scan += 3;
626 continue;
627 }
628 if (src_alpha1 == 0) {
629 dest_scan += 4;
630 src_scan += 3;
631 continue;
632 }
633 FX_BYTE dest_alpha = back_alpha + src_alpha1 - b ack_alpha * src_alpha1 / 255;
634 dest_scan[3] = dest_alpha;
635 int alpha_ratio = src_alpha1 * 255 / dest_alpha;
636 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
637 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
638 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
639 dest_scan += 4;
640 src_scan += 3;
641 continue;
642 }
643 int src_alpha = src_scan[-2];
644 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_ flags, a);
645 src_alpha = src_alpha * a / 255;
646 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha));
647 src_alpha = src_scan[-1];
648 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
649 src_alpha = src_alpha * a / 255;
650 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
651 src_alpha = src_scan[0];
652 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
653 src_alpha = src_alpha * a / 255;
654 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
655 dest_scan[3] = 255;
656 dest_scan += 4;
657 src_scan += 3;
658 }
659 }
660 }
661 }
662 } else {
663 for (int row = 0; row < nrows; row ++) {
664 int dest_row = row + top;
665 if (dest_row < 0 || dest_row >= bitmap.GetHeight()) {
666 continue;
667 }
668 FX_LPBYTE src_scan = src_buf + row * src_pitch + (start_col - le ft) * 3;
669 FX_LPBYTE dest_scan = dest_buf + dest_row * dest_pitch + start_c ol * Bpp;
670 if (bBGRStripe) {
671 if (x_subpixel == 0) {
672 for (int col = start_col; col < end_col; col ++) {
673 int src_alpha = src_scan[2];
674 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_ flags, a);
675 src_alpha = src_alpha * a / 255;
676 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha));
677 src_alpha = src_scan[1];
678 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
679 src_alpha = src_alpha * a / 255;
680 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
681 src_alpha = src_scan[0];
682 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
683 src_alpha = src_alpha * a / 255;
684 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
685 dest_scan += Bpp;
686 src_scan += 3;
687 }
688 } else if (x_subpixel == 1) {
689 int src_alpha = src_scan[1];
690 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flag s, a);
691 src_alpha = src_alpha * a / 255;
692 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAM MA(dest_scan[2]), r, src_alpha));
693 src_alpha = src_scan[0];
694 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flag s, a);
695 src_alpha = src_alpha * a / 255;
696 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAM MA(dest_scan[1]), g, src_alpha));
697 if (start_col > left) {
698 src_alpha = src_scan[-1];
699 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
700 src_alpha = src_alpha * a / 255;
701 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
702 }
703 dest_scan += Bpp;
704 src_scan += 3;
705 for (int col = start_col + 1; col < end_col - 1; col ++) {
706 int src_alpha = src_scan[1];
707 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_ flags, a);
708 src_alpha = src_alpha * a / 255;
709 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha));
710 src_alpha = src_scan[0];
711 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
712 src_alpha = src_alpha * a / 255;
713 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
714 src_alpha = src_scan[-1];
715 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
716 src_alpha = src_alpha * a / 255;
717 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
718 dest_scan += Bpp;
719 src_scan += 3;
720 }
721 } else {
722 int src_alpha = src_scan[0];
723 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flag s, a);
724 src_alpha = src_alpha * a / 255;
725 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAM MA(dest_scan[2]), r, src_alpha));
726 if (start_col > left) {
727 src_alpha = src_scan[-1];
728 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
729 src_alpha = src_alpha * a / 255;
730 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
731 src_alpha = src_scan[-2];
732 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
733 src_alpha = src_alpha * a / 255;
734 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
735 }
736 dest_scan += Bpp;
737 src_scan += 3;
738 for (int col = start_col + 1; col < end_col - 1; col ++) {
739 int src_alpha = src_scan[0];
740 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_ flags, a);
741 src_alpha = src_alpha * a / 255;
742 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha));
743 src_alpha = src_scan[-1];
744 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
745 src_alpha = src_alpha * a / 255;
746 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
747 src_alpha = src_scan[-2];
748 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
749 src_alpha = src_alpha * a / 255;
750 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
751 dest_scan += Bpp;
752 src_scan += 3;
753 }
754 }
755 } else {
756 if (x_subpixel == 0) {
757 for (int col = start_col; col < end_col; col ++) {
758 if (bNormal) {
759 int src_alpha1 = (src_scan[0] + src_scan[1] + sr c_scan[2]) / 3;
760 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, native text_flags, a);
761 src_alpha1 = src_alpha1 * a / 255;
762 if (src_alpha1 == 0) {
763 dest_scan += Bpp;
764 src_scan += 3;
765 continue;
766 }
767 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[2]), r, src_alpha1));
768 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[1]), g, src_alpha1));
769 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[0]), b, src_alpha1));
770 dest_scan += Bpp;
771 src_scan += 3;
772 continue;
773 }
774 int src_alpha = src_scan[0];
775 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_ flags, a);
776 src_alpha = src_alpha * a / 255;
777 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha));
778 src_alpha = src_scan[1];
779 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
780 src_alpha = src_alpha * a / 255;
781 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
782 src_alpha = src_scan[2];
783 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
784 src_alpha = src_alpha * a / 255;
785 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
786 dest_scan += Bpp;
787 src_scan += 3;
788 }
789 } else if (x_subpixel == 1) {
790 if (bNormal) {
791 int src_alpha1 = start_col > left ? (src_scan[0] + s rc_scan[1] + src_scan[-1]) / 3 : (src_scan[0] + src_scan[1]) / 3;
792 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext _flags, a);
793 src_alpha1 = src_alpha1 * a / 255;
794 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha1));
795 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha1));
796 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha1));
797 dest_scan += Bpp;
798 src_scan += 3;
799 } else {
800 if (start_col > left) {
801 int src_alpha = src_scan[-1];
802 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativet ext_flags, a);
803 src_alpha = src_alpha * a / 255;
804 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[2]), r, src_alpha));
805 }
806 int src_alpha = src_scan[0];
807 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
808 src_alpha = src_alpha * a / 255;
809 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
810 src_alpha = src_scan[1];
811 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
812 src_alpha = src_alpha * a / 255;
813 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
814 dest_scan += Bpp;
815 src_scan += 3;
816 }
817 for (int col = start_col + 1; col < end_col; col ++) {
818 if (bNormal) {
819 int src_alpha1 = (src_scan[0] + src_scan[1] + sr c_scan[-1]) / 3;
820 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, native text_flags, a);
821 src_alpha1 = src_alpha1 * a / 255;
822 if (src_alpha1 == 0) {
823 dest_scan += Bpp;
824 src_scan += 3;
825 continue;
826 }
827 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[2]), r, src_alpha1));
828 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[1]), g, src_alpha1));
829 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[0]), b, src_alpha1));
830 dest_scan += Bpp;
831 src_scan += 3;
832 continue;
833 }
834 int src_alpha = src_scan[-1];
835 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_ flags, a);
836 src_alpha = src_alpha * a / 255;
837 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha));
838 src_alpha = src_scan[0];
839 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
840 src_alpha = src_alpha * a / 255;
841 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
842 src_alpha = src_scan[1];
843 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
844 src_alpha = src_alpha * a / 255;
845 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
846 dest_scan += Bpp;
847 src_scan += 3;
848 }
849 } else {
850 if (bNormal) {
851 int src_alpha1 = start_col > left ? (src_scan[0] + s rc_scan[-2] + src_scan[-1]) / 3 : src_scan[0] / 3;
852 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext _flags, a);
853 src_alpha1 = src_alpha1 * a / 255;
854 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha1));
855 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha1));
856 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha1));
857 dest_scan += Bpp;
858 src_scan += 3;
859 } else {
860 if (start_col > left) {
861 int src_alpha = src_scan[-2];
862 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativet ext_flags, a);
863 src_alpha = src_alpha * a / 255;
864 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[2]), r, src_alpha));
865 src_alpha = src_scan[-1];
866 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativet ext_flags, a);
867 src_alpha = src_alpha * a / 255;
868 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[1]), g, src_alpha));
869 }
870 int src_alpha = src_scan[0];
871 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
872 src_alpha = src_alpha * a / 255;
873 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
874 dest_scan += Bpp;
875 src_scan += 3;
876 }
877 for (int col = start_col + 1; col < end_col; col ++) {
878 if (bNormal) {
879 int src_alpha1 = ((int)(src_scan[0]) + (int)(src _scan[-2]) + (int)(src_scan[-1])) / 3;
880 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, native text_flags, a);
881 src_alpha1 = src_alpha1 * a / 255;
882 if (src_alpha1 == 0) {
883 dest_scan += Bpp;
884 src_scan += 3;
885 continue;
886 }
887 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[2]), r, src_alpha1));
888 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[1]), g, src_alpha1));
889 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERG E(FX_GAMMA(dest_scan[0]), b, src_alpha1));
890 dest_scan += Bpp;
891 src_scan += 3;
892 continue;
893 }
894 int src_alpha = src_scan[-2];
895 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_ flags, a);
896 src_alpha = src_alpha * a / 255;
897 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[2]), r, src_alpha));
898 src_alpha = src_scan[-1];
899 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_ flags, a);
900 src_alpha = src_alpha * a / 255;
901 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[1]), g, src_alpha));
902 src_alpha = src_scan[0];
903 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_ flags, a);
904 src_alpha = src_alpha * a / 255;
905 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX _GAMMA(dest_scan[0]), b, src_alpha));
906 dest_scan += Bpp;
907 src_scan += 3;
908 }
909 }
910 }
911 }
912 }
913 }
914 if (bitmap.IsAlphaMask()) {
915 SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color, alpha_flag, pIccTransform);
916 } else {
917 SetDIBits(&bitmap, bmp_rect.left, bmp_rect.top);
918 }
919 FX_Free(pGlyphAndPos); 328 FX_Free(pGlyphAndPos);
920 return TRUE; 329 return TRUE;
921 } 330 }
922 FX_BOOL CFX_RenderDevice::DrawTextPath(int nChars, const FXTEXT_CHARPOS* pCharPo s, 331 int pixel_width = FXSYS_round(bmp_rect.Width() * scale_x);
923 CFX_Font* pFont, CFX_FontCache* pCache, 332 int pixel_height = FXSYS_round(bmp_rect.Height() * scale_y);
924 FX_FLOAT font_size, const CFX_AffineMatri x* pText2User, 333 int pixel_left = FXSYS_round(bmp_rect.left * scale_x);
925 const CFX_AffineMatrix* pUser2Device, con st CFX_GraphStateData* pGraphState, 334 int pixel_top = FXSYS_round(bmp_rect.top * scale_y);
926 FX_DWORD fill_color, FX_ARGB stroke_color , CFX_PathData* pClippingPath, int nFlag, 335 if (anti_alias == FXFT_RENDER_MODE_MONO) {
927 int alpha_flag, void* pIccTransform, int blend_type) 336 CFX_DIBitmap bitmap;
928 { 337 if (!bitmap.Create(pixel_width, pixel_height, FXDIB_1bppMask)) {
929 if (pCache == NULL) { 338 FX_Free(pGlyphAndPos);
930 pCache = CFX_GEModule::Get()->GetFontCache(); 339 return FALSE;
931 } 340 }
932 CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont); 341 bitmap.Clear(0);
933 FX_FONTCACHE_DEFINE(pCache, pFont); 342 for (iChar = 0; iChar < nChars; iChar++) {
934 for (int iChar = 0; iChar < nChars; iChar ++) { 343 FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
935 const FXTEXT_CHARPOS& charpos = pCharPos[iChar]; 344 if (glyph.m_pGlyph == NULL) {
936 CFX_AffineMatrix matrix; 345 continue;
937 if (charpos.m_bGlyphAdjust) 346 }
938 matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], 347 const CFX_DIBitmap* pGlyph = &glyph.m_pGlyph->m_Bitmap;
939 charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); 348 bitmap.TransferBitmap(
940 matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, charpos.m_O riginY); 349 glyph.m_OriginX + glyph.m_pGlyph->m_Left - pixel_left,
941 const CFX_PathData* pPath = pFaceCache->LoadGlyphPath(pFont, charpos.m_G lyphIndex, charpos.m_FontCharWidth); 350 glyph.m_OriginY - glyph.m_pGlyph->m_Top - pixel_top,
942 if (pPath == NULL) { 351 pGlyph->GetWidth(),
943 continue; 352 pGlyph->GetHeight(),
353 pGlyph,
354 0,
355 0);
356 }
357 FX_Free(pGlyphAndPos);
358 return SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color);
359 }
360 CFX_DIBitmap bitmap;
361 if (m_bpp == 8) {
362 if (!bitmap.Create(pixel_width, pixel_height, FXDIB_8bppMask)) {
363 FX_Free(pGlyphAndPos);
364 return FALSE;
365 }
366 } else {
367 if (!CreateCompatibleBitmap(&bitmap, pixel_width, pixel_height)) {
368 FX_Free(pGlyphAndPos);
369 return FALSE;
370 }
371 }
372 if (!bitmap.HasAlpha() && !bitmap.IsAlphaMask()) {
373 bitmap.Clear(0xFFFFFFFF);
374 if (!GetDIBits(&bitmap, bmp_rect.left, bmp_rect.top)) {
375 FX_Free(pGlyphAndPos);
376 return FALSE;
377 }
378 } else {
379 bitmap.Clear(0);
380 if (bitmap.m_pAlphaMask) {
381 bitmap.m_pAlphaMask->Clear(0);
382 }
383 }
384 int dest_width = pixel_width;
385 FX_LPBYTE dest_buf = bitmap.GetBuffer();
386 int dest_pitch = bitmap.GetPitch();
387 int Bpp = bitmap.GetBPP() / 8;
388 int a, r, g, b;
389 if (anti_alias == FXFT_RENDER_MODE_LCD) {
390 _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
391 ArgbDecode(fill_color, a, r, g, b);
392 r = FX_GAMMA(r);
393 g = FX_GAMMA(g);
394 b = FX_GAMMA(b);
395 }
396 for (iChar = 0; iChar < nChars; iChar++) {
397 FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
398 if (glyph.m_pGlyph == NULL) {
399 continue;
400 }
401 const CFX_DIBitmap* pGlyph = &glyph.m_pGlyph->m_Bitmap;
402 int left = glyph.m_OriginX + glyph.m_pGlyph->m_Left - pixel_left;
403 int top = glyph.m_OriginY - glyph.m_pGlyph->m_Top - pixel_top;
404 int ncols = pGlyph->GetWidth();
405 int nrows = pGlyph->GetHeight();
406 if (anti_alias == FXFT_RENDER_MODE_NORMAL) {
407 if (!bitmap.CompositeMask(left,
408 top,
409 ncols,
410 nrows,
411 pGlyph,
412 fill_color,
413 0,
414 0,
415 FXDIB_BLEND_NORMAL,
416 NULL,
417 FALSE,
418 alpha_flag,
419 pIccTransform)) {
420 FX_Free(pGlyphAndPos);
421 return FALSE;
422 }
423 continue;
424 }
425 FX_BOOL bBGRStripe = text_flags & FXTEXT_BGR_STRIPE;
426 ncols /= 3;
427 int x_subpixel = (int)(glyph.m_fOriginX * 3) % 3;
428 FX_LPBYTE src_buf = pGlyph->GetBuffer();
429 int src_pitch = pGlyph->GetPitch();
430 int start_col = left;
431 if (start_col < 0) {
432 start_col = 0;
433 }
434 int end_col = left + ncols;
435 if (end_col > dest_width) {
436 end_col = dest_width;
437 }
438 if (start_col >= end_col) {
439 continue;
440 }
441 if (bitmap.GetFormat() == FXDIB_Argb) {
442 for (int row = 0; row < nrows; row++) {
443 int dest_row = row + top;
444 if (dest_row < 0 || dest_row >= bitmap.GetHeight()) {
445 continue;
944 } 446 }
945 matrix.Concat(*pText2User); 447 FX_LPBYTE src_scan = src_buf + row * src_pitch + (start_col - left) * 3;
946 CFX_PathData TransformedPath(*pPath); 448 FX_LPBYTE dest_scan =
947 TransformedPath.Transform(&matrix); 449 dest_buf + dest_row * dest_pitch + (start_col << 2);
948 FX_BOOL bHasAlpha = FXGETFLAG_COLORTYPE(alpha_flag) ? 450 if (bBGRStripe) {
949 (FXGETFLAG_ALPHA_FILL(alpha_flag) || FXGETFLAG_ALPHA _STROKE(alpha_flag)) : 451 if (x_subpixel == 0) {
950 (fill_color || stroke_color); 452 for (int col = start_col; col < end_col; col++) {
951 if (bHasAlpha) { 453 int src_alpha = src_scan[2];
952 int fill_mode = nFlag; 454 src_alpha = src_alpha * a / 255;
953 if (FXGETFLAG_COLORTYPE(alpha_flag)) { 455 dest_scan[2] = FX_GAMMA_INVERSE(
954 if (FXGETFLAG_ALPHA_FILL(alpha_flag)) { 456 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
955 fill_mode |= FXFILL_WINDING; 457 src_alpha = src_scan[1];
458 src_alpha = src_alpha * a / 255;
459 dest_scan[1] = FX_GAMMA_INVERSE(
460 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
461 src_alpha = src_scan[0];
462 src_alpha = src_alpha * a / 255;
463 dest_scan[0] = FX_GAMMA_INVERSE(
464 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
465 dest_scan[3] = 255;
466 dest_scan += 4;
467 src_scan += 3;
468 }
469 } else if (x_subpixel == 1) {
470 int src_alpha = src_scan[1];
471 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
472 src_alpha = src_alpha * a / 255;
473 dest_scan[2] = FX_GAMMA_INVERSE(
474 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
475 src_alpha = src_scan[0];
476 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
477 src_alpha = src_alpha * a / 255;
478 dest_scan[1] = FX_GAMMA_INVERSE(
479 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
480 if (start_col > left) {
481 src_alpha = src_scan[-1];
482 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
483 src_alpha = src_alpha * a / 255;
484 dest_scan[0] = FX_GAMMA_INVERSE(
485 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
486 }
487 dest_scan[3] = 255;
488 dest_scan += 4;
489 src_scan += 3;
490 for (int col = start_col + 1; col < end_col - 1; col++) {
491 int src_alpha = src_scan[1];
492 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
493 src_alpha = src_alpha * a / 255;
494 dest_scan[2] = FX_GAMMA_INVERSE(
495 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
496 src_alpha = src_scan[0];
497 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
498 src_alpha = src_alpha * a / 255;
499 dest_scan[1] = FX_GAMMA_INVERSE(
500 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
501 src_alpha = src_scan[-1];
502 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
503 src_alpha = src_alpha * a / 255;
504 dest_scan[0] = FX_GAMMA_INVERSE(
505 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
506 dest_scan[3] = 255;
507 dest_scan += 4;
508 src_scan += 3;
509 }
510 } else {
511 int src_alpha = src_scan[0];
512 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
513 src_alpha = src_alpha * a / 255;
514 dest_scan[2] = FX_GAMMA_INVERSE(
515 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
516 if (start_col > left) {
517 src_alpha = src_scan[-1];
518 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
519 src_alpha = src_alpha * a / 255;
520 dest_scan[1] = FX_GAMMA_INVERSE(
521 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
522 src_alpha = src_scan[-2];
523 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
524 src_alpha = src_alpha * a / 255;
525 dest_scan[0] = FX_GAMMA_INVERSE(
526 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
527 }
528 dest_scan[3] = 255;
529 dest_scan += 4;
530 src_scan += 3;
531 for (int col = start_col + 1; col < end_col - 1; col++) {
532 int src_alpha = src_scan[0];
533 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
534 src_alpha = src_alpha * a / 255;
535 dest_scan[2] = FX_GAMMA_INVERSE(
536 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
537 src_alpha = src_scan[-1];
538 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
539 src_alpha = src_alpha * a / 255;
540 dest_scan[1] = FX_GAMMA_INVERSE(
541 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
542 src_alpha = src_scan[-2];
543 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
544 src_alpha = src_alpha * a / 255;
545 dest_scan[0] = FX_GAMMA_INVERSE(
546 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
547 dest_scan[3] = 255;
548 dest_scan += 4;
549 src_scan += 3;
550 }
551 }
552 } else {
553 if (x_subpixel == 0) {
554 for (int col = start_col; col < end_col; col++) {
555 if (bNormal) {
556 int src_alpha1 = (src_scan[0] + src_scan[1] + src_scan[2]) / 3;
557 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
558 src_alpha1 = src_alpha1 * a / 255;
559 FX_BYTE back_alpha = dest_scan[3];
560 if (back_alpha == 0) {
561 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
562 dest_scan += 4;
563 src_scan += 3;
564 continue;
956 } 565 }
566 if (src_alpha1 == 0) {
567 dest_scan += 4;
568 src_scan += 3;
569 continue;
570 }
571 FX_BYTE dest_alpha =
572 back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
573 dest_scan[3] = dest_alpha;
574 int alpha_ratio = src_alpha1 * 255 / dest_alpha;
575 dest_scan[2] = FX_GAMMA_INVERSE(
576 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
577 dest_scan[1] = FX_GAMMA_INVERSE(
578 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
579 dest_scan[0] = FX_GAMMA_INVERSE(
580 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
581 dest_scan += 4;
582 src_scan += 3;
583 continue;
584 }
585 int src_alpha = src_scan[0];
586 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
587 src_alpha = src_alpha * a / 255;
588 dest_scan[2] = FX_GAMMA_INVERSE(
589 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
590 src_alpha = src_scan[1];
591 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
592 src_alpha = src_alpha * a / 255;
593 dest_scan[1] = FX_GAMMA_INVERSE(
594 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
595 src_alpha = src_scan[2];
596 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
597 src_alpha = src_alpha * a / 255;
598 dest_scan[0] = FX_GAMMA_INVERSE(
599 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
600 dest_scan[3] = 255;
601 dest_scan += 4;
602 src_scan += 3;
603 }
604 } else if (x_subpixel == 1) {
605 if (bNormal) {
606 int src_alpha1 =
607 start_col > left
608 ? ((src_scan[-1] + src_scan[0] + src_scan[1]) / 3)
609 : ((src_scan[0] + src_scan[1]) / 3);
610 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
611 src_alpha1 = src_alpha1 * a / 255;
612 if (src_alpha1 == 0) {
613 dest_scan += 4;
614 src_scan += 3;
615 } else {
616 FX_BYTE back_alpha = dest_scan[3];
617 if (back_alpha == 0) {
618 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
619 } else {
620 FX_BYTE dest_alpha =
621 back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
622 dest_scan[3] = dest_alpha;
623 int alpha_ratio = src_alpha1 * 255 / dest_alpha;
624 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
625 FX_GAMMA(dest_scan[2]), r, alpha_ratio));
626 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
627 FX_GAMMA(dest_scan[1]), g, alpha_ratio));
628 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
629 FX_GAMMA(dest_scan[0]), b, alpha_ratio));
630 }
631 dest_scan += 4;
632 src_scan += 3;
633 }
957 } else { 634 } else {
958 if (fill_color) { 635 if (start_col > left) {
959 fill_mode |= FXFILL_WINDING; 636 int src_alpha = src_scan[-1];
637 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
638 src_alpha = src_alpha * a / 255;
639 dest_scan[2] = FX_GAMMA_INVERSE(
640 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
641 }
642 int src_alpha = src_scan[0];
643 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
644 src_alpha = src_alpha * a / 255;
645 dest_scan[1] = FX_GAMMA_INVERSE(
646 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
647 src_alpha = src_scan[1];
648 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
649 src_alpha = src_alpha * a / 255;
650 dest_scan[0] = FX_GAMMA_INVERSE(
651 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
652 dest_scan[3] = 255;
653 dest_scan += 4;
654 src_scan += 3;
655 }
656 for (int col = start_col + 1; col < end_col; col++) {
657 if (bNormal) {
658 int src_alpha1 = (src_scan[-1] + src_scan[0] + src_scan[1]) / 3;
659 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
660 src_alpha1 = src_alpha1 * a / 255;
661 FX_BYTE back_alpha = dest_scan[3];
662 if (back_alpha == 0) {
663 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
664 dest_scan += 4;
665 src_scan += 3;
666 continue;
960 } 667 }
668 if (src_alpha1 == 0) {
669 dest_scan += 4;
670 src_scan += 3;
671 continue;
672 }
673 FX_BYTE dest_alpha =
674 back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
675 dest_scan[3] = dest_alpha;
676 int alpha_ratio = src_alpha1 * 255 / dest_alpha;
677 dest_scan[2] = FX_GAMMA_INVERSE(
678 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
679 dest_scan[1] = FX_GAMMA_INVERSE(
680 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
681 dest_scan[0] = FX_GAMMA_INVERSE(
682 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
683 dest_scan += 4;
684 src_scan += 3;
685 continue;
686 }
687 int src_alpha = src_scan[-1];
688 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
689 src_alpha = src_alpha * a / 255;
690 dest_scan[2] = FX_GAMMA_INVERSE(
691 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
692 src_alpha = src_scan[0];
693 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
694 src_alpha = src_alpha * a / 255;
695 dest_scan[1] = FX_GAMMA_INVERSE(
696 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
697 src_alpha = src_scan[1];
698 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
699 src_alpha = src_alpha * a / 255;
700 dest_scan[0] = FX_GAMMA_INVERSE(
701 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
702 dest_scan[3] = 255;
703 dest_scan += 4;
704 src_scan += 3;
961 } 705 }
962 fill_mode |= FX_FILL_TEXT_MODE; 706 } else {
963 if (!DrawPath(&TransformedPath, pUser2Device, pGraphState, fill_colo r, stroke_color, fill_mode, alpha_flag, pIccTransform, blend_type)) { 707 if (bNormal) {
964 return FALSE; 708 int src_alpha1 =
709 start_col > left
710 ? ((src_scan[-2] + src_scan[-1] + src_scan[0]) / 3)
711 : ((src_scan[0]) / 3);
712 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
713 src_alpha1 = src_alpha1 * a / 255;
714 if (src_alpha1 == 0) {
715 dest_scan += 4;
716 src_scan += 3;
717 } else {
718 FX_BYTE back_alpha = dest_scan[3];
719 if (back_alpha == 0) {
720 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
721 } else {
722 FX_BYTE dest_alpha =
723 back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
724 dest_scan[3] = dest_alpha;
725 int alpha_ratio = src_alpha1 * 255 / dest_alpha;
726 dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
727 FX_GAMMA(dest_scan[2]), r, alpha_ratio));
728 dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
729 FX_GAMMA(dest_scan[1]), g, alpha_ratio));
730 dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(
731 FX_GAMMA(dest_scan[0]), b, alpha_ratio));
732 }
733 dest_scan += 4;
734 src_scan += 3;
735 }
736 } else {
737 if (start_col > left) {
738 int src_alpha = src_scan[-2];
739 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
740 src_alpha = src_alpha * a / 255;
741 dest_scan[2] = FX_GAMMA_INVERSE(
742 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
743 src_alpha = src_scan[-1];
744 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
745 src_alpha = src_alpha * a / 255;
746 dest_scan[1] = FX_GAMMA_INVERSE(
747 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
748 }
749 int src_alpha = src_scan[0];
750 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
751 src_alpha = src_alpha * a / 255;
752 dest_scan[0] = FX_GAMMA_INVERSE(
753 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
754 dest_scan[3] = 255;
755 dest_scan += 4;
756 src_scan += 3;
965 } 757 }
758 for (int col = start_col + 1; col < end_col; col++) {
759 if (bNormal) {
760 int src_alpha1 =
761 (src_scan[-2] + src_scan[-1] + src_scan[0]) / 3;
762 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
763 src_alpha1 = src_alpha1 * a / 255;
764 FX_BYTE back_alpha = dest_scan[3];
765 if (back_alpha == 0) {
766 FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
767 dest_scan += 4;
768 src_scan += 3;
769 continue;
770 }
771 if (src_alpha1 == 0) {
772 dest_scan += 4;
773 src_scan += 3;
774 continue;
775 }
776 FX_BYTE dest_alpha =
777 back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
778 dest_scan[3] = dest_alpha;
779 int alpha_ratio = src_alpha1 * 255 / dest_alpha;
780 dest_scan[2] = FX_GAMMA_INVERSE(
781 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
782 dest_scan[1] = FX_GAMMA_INVERSE(
783 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
784 dest_scan[0] = FX_GAMMA_INVERSE(
785 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
786 dest_scan += 4;
787 src_scan += 3;
788 continue;
789 }
790 int src_alpha = src_scan[-2];
791 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
792 src_alpha = src_alpha * a / 255;
793 dest_scan[2] = FX_GAMMA_INVERSE(
794 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
795 src_alpha = src_scan[-1];
796 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
797 src_alpha = src_alpha * a / 255;
798 dest_scan[1] = FX_GAMMA_INVERSE(
799 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
800 src_alpha = src_scan[0];
801 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
802 src_alpha = src_alpha * a / 255;
803 dest_scan[0] = FX_GAMMA_INVERSE(
804 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
805 dest_scan[3] = 255;
806 dest_scan += 4;
807 src_scan += 3;
808 }
809 }
966 } 810 }
967 if (pClippingPath) { 811 }
968 pClippingPath->Append(&TransformedPath, pUser2Device); 812 } else {
813 for (int row = 0; row < nrows; row++) {
814 int dest_row = row + top;
815 if (dest_row < 0 || dest_row >= bitmap.GetHeight()) {
816 continue;
969 } 817 }
970 } 818 FX_LPBYTE src_scan = src_buf + row * src_pitch + (start_col - left) * 3;
971 return TRUE; 819 FX_LPBYTE dest_scan =
972 } 820 dest_buf + dest_row * dest_pitch + start_col * Bpp;
973 CFX_FontCache::~CFX_FontCache() 821 if (bBGRStripe) {
974 { 822 if (x_subpixel == 0) {
975 FreeCache(TRUE); 823 for (int col = start_col; col < end_col; col++) {
976 } 824 int src_alpha = src_scan[2];
977 CFX_FaceCache* CFX_FontCache::GetCachedFace(CFX_Font* pFont) 825 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
978 { 826 src_alpha = src_alpha * a / 255;
979 FX_BOOL bExternal = pFont->GetFace() == NULL; 827 dest_scan[2] = FX_GAMMA_INVERSE(
980 void* face = bExternal ? pFont->GetSubstFont()->m_ExtHandle : pFont->GetFace (); 828 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
981 CFX_FTCacheMap& map = bExternal ? m_ExtFaceMap : m_FTFaceMap; 829 src_alpha = src_scan[1];
982 CFX_CountedFaceCache* counted_face_cache = NULL; 830 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
983 if (map.Lookup((FXFT_Face)face, counted_face_cache)) { 831 src_alpha = src_alpha * a / 255;
984 counted_face_cache->m_nCount++; 832 dest_scan[1] = FX_GAMMA_INVERSE(
985 return counted_face_cache->m_Obj; 833 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
986 } 834 src_alpha = src_scan[0];
987 CFX_FaceCache* face_cache = NULL; 835 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
988 face_cache = FX_NEW CFX_FaceCache(bExternal ? NULL : (FXFT_Face)face); 836 src_alpha = src_alpha * a / 255;
989 if (face_cache == NULL) { 837 dest_scan[0] = FX_GAMMA_INVERSE(
990 return NULL; 838 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
991 } 839 dest_scan += Bpp;
992 counted_face_cache = FX_NEW CFX_CountedFaceCache; 840 src_scan += 3;
993 if (!counted_face_cache) { 841 }
994 if (face_cache) { 842 } else if (x_subpixel == 1) {
995 delete face_cache; 843 int src_alpha = src_scan[1];
996 face_cache = NULL; 844 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
845 src_alpha = src_alpha * a / 255;
846 dest_scan[2] = FX_GAMMA_INVERSE(
847 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
848 src_alpha = src_scan[0];
849 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
850 src_alpha = src_alpha * a / 255;
851 dest_scan[1] = FX_GAMMA_INVERSE(
852 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
853 if (start_col > left) {
854 src_alpha = src_scan[-1];
855 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
856 src_alpha = src_alpha * a / 255;
857 dest_scan[0] = FX_GAMMA_INVERSE(
858 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
859 }
860 dest_scan += Bpp;
861 src_scan += 3;
862 for (int col = start_col + 1; col < end_col - 1; col++) {
863 int src_alpha = src_scan[1];
864 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
865 src_alpha = src_alpha * a / 255;
866 dest_scan[2] = FX_GAMMA_INVERSE(
867 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
868 src_alpha = src_scan[0];
869 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
870 src_alpha = src_alpha * a / 255;
871 dest_scan[1] = FX_GAMMA_INVERSE(
872 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
873 src_alpha = src_scan[-1];
874 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
875 src_alpha = src_alpha * a / 255;
876 dest_scan[0] = FX_GAMMA_INVERSE(
877 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
878 dest_scan += Bpp;
879 src_scan += 3;
880 }
881 } else {
882 int src_alpha = src_scan[0];
883 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
884 src_alpha = src_alpha * a / 255;
885 dest_scan[2] = FX_GAMMA_INVERSE(
886 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
887 if (start_col > left) {
888 src_alpha = src_scan[-1];
889 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
890 src_alpha = src_alpha * a / 255;
891 dest_scan[1] = FX_GAMMA_INVERSE(
892 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
893 src_alpha = src_scan[-2];
894 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
895 src_alpha = src_alpha * a / 255;
896 dest_scan[0] = FX_GAMMA_INVERSE(
897 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
898 }
899 dest_scan += Bpp;
900 src_scan += 3;
901 for (int col = start_col + 1; col < end_col - 1; col++) {
902 int src_alpha = src_scan[0];
903 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
904 src_alpha = src_alpha * a / 255;
905 dest_scan[2] = FX_GAMMA_INVERSE(
906 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
907 src_alpha = src_scan[-1];
908 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
909 src_alpha = src_alpha * a / 255;
910 dest_scan[1] = FX_GAMMA_INVERSE(
911 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
912 src_alpha = src_scan[-2];
913 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
914 src_alpha = src_alpha * a / 255;
915 dest_scan[0] = FX_GAMMA_INVERSE(
916 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
917 dest_scan += Bpp;
918 src_scan += 3;
919 }
920 }
921 } else {
922 if (x_subpixel == 0) {
923 for (int col = start_col; col < end_col; col++) {
924 if (bNormal) {
925 int src_alpha1 = (src_scan[0] + src_scan[1] + src_scan[2]) / 3;
926 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
927 src_alpha1 = src_alpha1 * a / 255;
928 if (src_alpha1 == 0) {
929 dest_scan += Bpp;
930 src_scan += 3;
931 continue;
932 }
933 dest_scan[2] = FX_GAMMA_INVERSE(
934 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
935 dest_scan[1] = FX_GAMMA_INVERSE(
936 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
937 dest_scan[0] = FX_GAMMA_INVERSE(
938 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
939 dest_scan += Bpp;
940 src_scan += 3;
941 continue;
942 }
943 int src_alpha = src_scan[0];
944 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
945 src_alpha = src_alpha * a / 255;
946 dest_scan[2] = FX_GAMMA_INVERSE(
947 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
948 src_alpha = src_scan[1];
949 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
950 src_alpha = src_alpha * a / 255;
951 dest_scan[1] = FX_GAMMA_INVERSE(
952 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
953 src_alpha = src_scan[2];
954 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
955 src_alpha = src_alpha * a / 255;
956 dest_scan[0] = FX_GAMMA_INVERSE(
957 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
958 dest_scan += Bpp;
959 src_scan += 3;
960 }
961 } else if (x_subpixel == 1) {
962 if (bNormal) {
963 int src_alpha1 =
964 start_col > left
965 ? (src_scan[0] + src_scan[1] + src_scan[-1]) / 3
966 : (src_scan[0] + src_scan[1]) / 3;
967 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
968 src_alpha1 = src_alpha1 * a / 255;
969 dest_scan[2] = FX_GAMMA_INVERSE(
970 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
971 dest_scan[1] = FX_GAMMA_INVERSE(
972 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
973 dest_scan[0] = FX_GAMMA_INVERSE(
974 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
975 dest_scan += Bpp;
976 src_scan += 3;
977 } else {
978 if (start_col > left) {
979 int src_alpha = src_scan[-1];
980 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
981 src_alpha = src_alpha * a / 255;
982 dest_scan[2] = FX_GAMMA_INVERSE(
983 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
984 }
985 int src_alpha = src_scan[0];
986 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
987 src_alpha = src_alpha * a / 255;
988 dest_scan[1] = FX_GAMMA_INVERSE(
989 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
990 src_alpha = src_scan[1];
991 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
992 src_alpha = src_alpha * a / 255;
993 dest_scan[0] = FX_GAMMA_INVERSE(
994 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
995 dest_scan += Bpp;
996 src_scan += 3;
997 }
998 for (int col = start_col + 1; col < end_col; col++) {
999 if (bNormal) {
1000 int src_alpha1 = (src_scan[0] + src_scan[1] + src_scan[-1]) / 3;
1001 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
1002 src_alpha1 = src_alpha1 * a / 255;
1003 if (src_alpha1 == 0) {
1004 dest_scan += Bpp;
1005 src_scan += 3;
1006 continue;
1007 }
1008 dest_scan[2] = FX_GAMMA_INVERSE(
1009 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
1010 dest_scan[1] = FX_GAMMA_INVERSE(
1011 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
1012 dest_scan[0] = FX_GAMMA_INVERSE(
1013 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
1014 dest_scan += Bpp;
1015 src_scan += 3;
1016 continue;
1017 }
1018 int src_alpha = src_scan[-1];
1019 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
1020 src_alpha = src_alpha * a / 255;
1021 dest_scan[2] = FX_GAMMA_INVERSE(
1022 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
1023 src_alpha = src_scan[0];
1024 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
1025 src_alpha = src_alpha * a / 255;
1026 dest_scan[1] = FX_GAMMA_INVERSE(
1027 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
1028 src_alpha = src_scan[1];
1029 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
1030 src_alpha = src_alpha * a / 255;
1031 dest_scan[0] = FX_GAMMA_INVERSE(
1032 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
1033 dest_scan += Bpp;
1034 src_scan += 3;
1035 }
1036 } else {
1037 if (bNormal) {
1038 int src_alpha1 =
1039 start_col > left
1040 ? (src_scan[0] + src_scan[-2] + src_scan[-1]) / 3
1041 : src_scan[0] / 3;
1042 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
1043 src_alpha1 = src_alpha1 * a / 255;
1044 dest_scan[2] = FX_GAMMA_INVERSE(
1045 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
1046 dest_scan[1] = FX_GAMMA_INVERSE(
1047 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
1048 dest_scan[0] = FX_GAMMA_INVERSE(
1049 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
1050 dest_scan += Bpp;
1051 src_scan += 3;
1052 } else {
1053 if (start_col > left) {
1054 int src_alpha = src_scan[-2];
1055 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
1056 src_alpha = src_alpha * a / 255;
1057 dest_scan[2] = FX_GAMMA_INVERSE(
1058 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
1059 src_alpha = src_scan[-1];
1060 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
1061 src_alpha = src_alpha * a / 255;
1062 dest_scan[1] = FX_GAMMA_INVERSE(
1063 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
1064 }
1065 int src_alpha = src_scan[0];
1066 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
1067 src_alpha = src_alpha * a / 255;
1068 dest_scan[0] = FX_GAMMA_INVERSE(
1069 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
1070 dest_scan += Bpp;
1071 src_scan += 3;
1072 }
1073 for (int col = start_col + 1; col < end_col; col++) {
1074 if (bNormal) {
1075 int src_alpha1 = ((int)(src_scan[0]) + (int)(src_scan[-2]) +
1076 (int)(src_scan[-1])) /
1077 3;
1078 ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
1079 src_alpha1 = src_alpha1 * a / 255;
1080 if (src_alpha1 == 0) {
1081 dest_scan += Bpp;
1082 src_scan += 3;
1083 continue;
1084 }
1085 dest_scan[2] = FX_GAMMA_INVERSE(
1086 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
1087 dest_scan[1] = FX_GAMMA_INVERSE(
1088 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
1089 dest_scan[0] = FX_GAMMA_INVERSE(
1090 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
1091 dest_scan += Bpp;
1092 src_scan += 3;
1093 continue;
1094 }
1095 int src_alpha = src_scan[-2];
1096 ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
1097 src_alpha = src_alpha * a / 255;
1098 dest_scan[2] = FX_GAMMA_INVERSE(
1099 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
1100 src_alpha = src_scan[-1];
1101 ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
1102 src_alpha = src_alpha * a / 255;
1103 dest_scan[1] = FX_GAMMA_INVERSE(
1104 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
1105 src_alpha = src_scan[0];
1106 ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
1107 src_alpha = src_alpha * a / 255;
1108 dest_scan[0] = FX_GAMMA_INVERSE(
1109 FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
1110 dest_scan += Bpp;
1111 src_scan += 3;
1112 }
1113 }
997 } 1114 }
998 return NULL; 1115 }
999 } 1116 }
1000 counted_face_cache->m_nCount = 2; 1117 }
1001 counted_face_cache->m_Obj = face_cache; 1118 if (bitmap.IsAlphaMask()) {
1002 map.SetAt((FXFT_Face)face, counted_face_cache); 1119 SetBitMask(&bitmap,
1003 return face_cache; 1120 bmp_rect.left,
1004 } 1121 bmp_rect.top,
1005 void CFX_FontCache::ReleaseCachedFace(CFX_Font* pFont) 1122 fill_color,
1006 { 1123 alpha_flag,
1007 FX_BOOL bExternal = pFont->GetFace() == NULL; 1124 pIccTransform);
1008 void* face = bExternal ? pFont->GetSubstFont()->m_ExtHandle : pFont->GetFace (); 1125 } else {
1009 CFX_FTCacheMap& map = bExternal ? m_ExtFaceMap : m_FTFaceMap; 1126 SetDIBits(&bitmap, bmp_rect.left, bmp_rect.top);
1010 CFX_CountedFaceCache* counted_face_cache = NULL; 1127 }
1011 if (!map.Lookup((FXFT_Face)face, counted_face_cache)) { 1128 FX_Free(pGlyphAndPos);
1012 return; 1129 return TRUE;
1013 } 1130 }
1014 if (counted_face_cache->m_nCount > 1) { 1131 FX_BOOL CFX_RenderDevice::DrawTextPath(int nChars,
1015 counted_face_cache->m_nCount--; 1132 const FXTEXT_CHARPOS* pCharPos,
1016 } 1133 CFX_Font* pFont,
1017 } 1134 CFX_FontCache* pCache,
1018 void CFX_FontCache::FreeCache(FX_BOOL bRelease) 1135 FX_FLOAT font_size,
1019 { 1136 const CFX_AffineMatrix* pText2User,
1020 { 1137 const CFX_AffineMatrix* pUser2Device,
1021 FX_POSITION pos; 1138 const CFX_GraphStateData* pGraphState,
1022 pos = m_FTFaceMap.GetStartPosition(); 1139 FX_DWORD fill_color,
1023 while (pos) { 1140 FX_ARGB stroke_color,
1024 FXFT_Face face; 1141 CFX_PathData* pClippingPath,
1025 CFX_CountedFaceCache* cache; 1142 int nFlag,
1026 m_FTFaceMap.GetNextAssoc(pos, face, cache); 1143 int alpha_flag,
1027 if (bRelease || cache->m_nCount < 2) { 1144 void* pIccTransform,
1028 delete cache->m_Obj; 1145 int blend_type) {
1029 delete cache; 1146 if (pCache == NULL) {
1030 m_FTFaceMap.RemoveKey(face); 1147 pCache = CFX_GEModule::Get()->GetFontCache();
1031 } 1148 }
1149 CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont);
1150 FX_FONTCACHE_DEFINE(pCache, pFont);
1151 for (int iChar = 0; iChar < nChars; iChar++) {
1152 const FXTEXT_CHARPOS& charpos = pCharPos[iChar];
1153 CFX_AffineMatrix matrix;
1154 if (charpos.m_bGlyphAdjust)
1155 matrix.Set(charpos.m_AdjustMatrix[0],
1156 charpos.m_AdjustMatrix[1],
1157 charpos.m_AdjustMatrix[2],
1158 charpos.m_AdjustMatrix[3],
1159 0,
1160 0);
1161 matrix.Concat(
1162 font_size, 0, 0, font_size, charpos.m_OriginX, charpos.m_OriginY);
1163 const CFX_PathData* pPath = pFaceCache->LoadGlyphPath(
1164 pFont, charpos.m_GlyphIndex, charpos.m_FontCharWidth);
1165 if (pPath == NULL) {
1166 continue;
1167 }
1168 matrix.Concat(*pText2User);
1169 CFX_PathData TransformedPath(*pPath);
1170 TransformedPath.Transform(&matrix);
1171 FX_BOOL bHasAlpha = FXGETFLAG_COLORTYPE(alpha_flag)
1172 ? (FXGETFLAG_ALPHA_FILL(alpha_flag) ||
1173 FXGETFLAG_ALPHA_STROKE(alpha_flag))
1174 : (fill_color || stroke_color);
1175 if (bHasAlpha) {
1176 int fill_mode = nFlag;
1177 if (FXGETFLAG_COLORTYPE(alpha_flag)) {
1178 if (FXGETFLAG_ALPHA_FILL(alpha_flag)) {
1179 fill_mode |= FXFILL_WINDING;
1032 } 1180 }
1033 pos = m_ExtFaceMap.GetStartPosition(); 1181 } else {
1034 while (pos) { 1182 if (fill_color) {
1035 FXFT_Face face; 1183 fill_mode |= FXFILL_WINDING;
1036 CFX_CountedFaceCache* cache;
1037 m_ExtFaceMap.GetNextAssoc(pos, face, cache);
1038 if (bRelease || cache->m_nCount < 2) {
1039 delete cache->m_Obj;
1040 delete cache;
1041 m_ExtFaceMap.RemoveKey(face);
1042 }
1043 } 1184 }
1044 } 1185 }
1045 } 1186 fill_mode |= FX_FILL_TEXT_MODE;
1046 CFX_FaceCache::CFX_FaceCache(FXFT_Face face) 1187 if (!DrawPath(&TransformedPath,
1047 { 1188 pUser2Device,
1048 m_Face = face; 1189 pGraphState,
1049 m_pBitmap = NULL; 1190 fill_color,
1050 } 1191 stroke_color,
1051 CFX_FaceCache::~CFX_FaceCache() 1192 fill_mode,
1052 { 1193 alpha_flag,
1053 FX_POSITION pos = m_SizeMap.GetStartPosition(); 1194 pIccTransform,
1054 CFX_ByteString Key; 1195 blend_type)) {
1196 return FALSE;
1197 }
1198 }
1199 if (pClippingPath) {
1200 pClippingPath->Append(&TransformedPath, pUser2Device);
1201 }
1202 }
1203 return TRUE;
1204 }
1205 CFX_FontCache::~CFX_FontCache() {
1206 FreeCache(TRUE);
1207 }
1208 CFX_FaceCache* CFX_FontCache::GetCachedFace(CFX_Font* pFont) {
1209 FX_BOOL bExternal = pFont->GetFace() == NULL;
1210 void* face =
1211 bExternal ? pFont->GetSubstFont()->m_ExtHandle : pFont->GetFace();
1212 CFX_FTCacheMap& map = bExternal ? m_ExtFaceMap : m_FTFaceMap;
1213 CFX_CountedFaceCache* counted_face_cache = NULL;
1214 if (map.Lookup((FXFT_Face)face, counted_face_cache)) {
1215 counted_face_cache->m_nCount++;
1216 return counted_face_cache->m_Obj;
1217 }
1218 CFX_FaceCache* face_cache = NULL;
1219 face_cache = FX_NEW CFX_FaceCache(bExternal ? NULL : (FXFT_Face)face);
1220 if (face_cache == NULL) {
1221 return NULL;
1222 }
1223 counted_face_cache = FX_NEW CFX_CountedFaceCache;
1224 if (!counted_face_cache) {
1225 if (face_cache) {
1226 delete face_cache;
1227 face_cache = NULL;
1228 }
1229 return NULL;
1230 }
1231 counted_face_cache->m_nCount = 2;
1232 counted_face_cache->m_Obj = face_cache;
1233 map.SetAt((FXFT_Face)face, counted_face_cache);
1234 return face_cache;
1235 }
1236 void CFX_FontCache::ReleaseCachedFace(CFX_Font* pFont) {
1237 FX_BOOL bExternal = pFont->GetFace() == NULL;
1238 void* face =
1239 bExternal ? pFont->GetSubstFont()->m_ExtHandle : pFont->GetFace();
1240 CFX_FTCacheMap& map = bExternal ? m_ExtFaceMap : m_FTFaceMap;
1241 CFX_CountedFaceCache* counted_face_cache = NULL;
1242 if (!map.Lookup((FXFT_Face)face, counted_face_cache)) {
1243 return;
1244 }
1245 if (counted_face_cache->m_nCount > 1) {
1246 counted_face_cache->m_nCount--;
1247 }
1248 }
1249 void CFX_FontCache::FreeCache(FX_BOOL bRelease) {
1250 {
1251 FX_POSITION pos;
1252 pos = m_FTFaceMap.GetStartPosition();
1253 while (pos) {
1254 FXFT_Face face;
1255 CFX_CountedFaceCache* cache;
1256 m_FTFaceMap.GetNextAssoc(pos, face, cache);
1257 if (bRelease || cache->m_nCount < 2) {
1258 delete cache->m_Obj;
1259 delete cache;
1260 m_FTFaceMap.RemoveKey(face);
1261 }
1262 }
1263 pos = m_ExtFaceMap.GetStartPosition();
1264 while (pos) {
1265 FXFT_Face face;
1266 CFX_CountedFaceCache* cache;
1267 m_ExtFaceMap.GetNextAssoc(pos, face, cache);
1268 if (bRelease || cache->m_nCount < 2) {
1269 delete cache->m_Obj;
1270 delete cache;
1271 m_ExtFaceMap.RemoveKey(face);
1272 }
1273 }
1274 }
1275 }
1276 CFX_FaceCache::CFX_FaceCache(FXFT_Face face) {
1277 m_Face = face;
1278 m_pBitmap = NULL;
1279 }
1280 CFX_FaceCache::~CFX_FaceCache() {
1281 FX_POSITION pos = m_SizeMap.GetStartPosition();
1282 CFX_ByteString Key;
1283 CFX_SizeGlyphCache* pSizeCache = NULL;
1284 while (pos) {
1285 m_SizeMap.GetNextAssoc(pos, Key, (void*&)pSizeCache);
1286 delete pSizeCache;
1287 }
1288 m_SizeMap.RemoveAll();
1289 pos = m_PathMap.GetStartPosition();
1290 FX_LPVOID key1;
1291 CFX_PathData* pPath;
1292 while (pos) {
1293 m_PathMap.GetNextAssoc(pos, key1, (FX_LPVOID&)pPath);
1294 delete pPath;
1295 }
1296 if (m_pBitmap) {
1297 delete m_pBitmap;
1298 }
1299 m_PathMap.RemoveAll();
1300 }
1301 #if ((_FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_) || defined(_FPDFAPI_MINI_))
1302 void CFX_FaceCache::InitPlatform() {
1303 }
1304 #endif
1305 CFX_GlyphBitmap* CFX_FaceCache::LookUpGlyphBitmap(
1306 CFX_Font* pFont,
1307 const CFX_AffineMatrix* pMatrix,
1308 CFX_ByteStringC& FaceGlyphsKey,
1309 FX_DWORD glyph_index,
1310 FX_BOOL bFontStyle,
1311 int dest_width,
1312 int anti_alias) {
1313 CFX_SizeGlyphCache* pSizeCache = NULL;
1314 if (!m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) {
1315 pSizeCache = FX_NEW CFX_SizeGlyphCache;
1316 if (pSizeCache == NULL) {
1317 return NULL;
1318 }
1319 m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache);
1320 }
1321 CFX_GlyphBitmap* pGlyphBitmap = NULL;
1322 if (pSizeCache->m_GlyphMap.Lookup((FX_LPVOID)(FX_UINTPTR) glyph_index,
1323 (void*&)pGlyphBitmap)) {
1324 return pGlyphBitmap;
1325 }
1326 pGlyphBitmap = RenderGlyph(
1327 pFont, glyph_index, bFontStyle, pMatrix, dest_width, anti_alias);
1328 if (pGlyphBitmap == NULL) {
1329 return NULL;
1330 }
1331 pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR) glyph_index,
1332 pGlyphBitmap);
1333 return pGlyphBitmap;
1334 }
1335 const CFX_GlyphBitmap* CFX_FaceCache::LoadGlyphBitmap(
1336 CFX_Font* pFont,
1337 FX_DWORD glyph_index,
1338 FX_BOOL bFontStyle,
1339 const CFX_AffineMatrix* pMatrix,
1340 int dest_width,
1341 int anti_alias,
1342 int& text_flags) {
1343 if (glyph_index == (FX_DWORD)-1) {
1344 return NULL;
1345 }
1346 _CFX_UniqueKeyGen keygen;
1347 #if ((_FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_) || defined(_FPDFAPI_MINI_))
1348 if (pFont->GetSubstFont())
1349 keygen.Generate(9,
1350 (int)(pMatrix->a * 10000),
1351 (int)(pMatrix->b * 10000),
1352 (int)(pMatrix->c * 10000),
1353 (int)(pMatrix->d * 10000),
1354 dest_width,
1355 anti_alias,
1356 pFont->GetSubstFont()->m_Weight,
1357 pFont->GetSubstFont()->m_ItalicAngle,
1358 pFont->IsVertical());
1359 else
1360 keygen.Generate(6,
1361 (int)(pMatrix->a * 10000),
1362 (int)(pMatrix->b * 10000),
1363 (int)(pMatrix->c * 10000),
1364 (int)(pMatrix->d * 10000),
1365 dest_width,
1366 anti_alias);
1367 #else
1368 if (text_flags & FXTEXT_NO_NATIVETEXT) {
1369 if (pFont->GetSubstFont())
1370 keygen.Generate(9,
1371 (int)(pMatrix->a * 10000),
1372 (int)(pMatrix->b * 10000),
1373 (int)(pMatrix->c * 10000),
1374 (int)(pMatrix->d * 10000),
1375 dest_width,
1376 anti_alias,
1377 pFont->GetSubstFont()->m_Weight,
1378 pFont->GetSubstFont()->m_ItalicAngle,
1379 pFont->IsVertical());
1380 else
1381 keygen.Generate(6,
1382 (int)(pMatrix->a * 10000),
1383 (int)(pMatrix->b * 10000),
1384 (int)(pMatrix->c * 10000),
1385 (int)(pMatrix->d * 10000),
1386 dest_width,
1387 anti_alias);
1388 } else {
1389 if (pFont->GetSubstFont())
1390 keygen.Generate(10,
1391 (int)(pMatrix->a * 10000),
1392 (int)(pMatrix->b * 10000),
1393 (int)(pMatrix->c * 10000),
1394 (int)(pMatrix->d * 10000),
1395 dest_width,
1396 anti_alias,
1397 pFont->GetSubstFont()->m_Weight,
1398 pFont->GetSubstFont()->m_ItalicAngle,
1399 pFont->IsVertical(),
1400 3);
1401 else
1402 keygen.Generate(7,
1403 (int)(pMatrix->a * 10000),
1404 (int)(pMatrix->b * 10000),
1405 (int)(pMatrix->c * 10000),
1406 (int)(pMatrix->d * 10000),
1407 dest_width,
1408 anti_alias,
1409 3);
1410 }
1411 #endif
1412 CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen);
1413 #if ((_FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_) || defined(_FPDFAPI_MINI_))
1414 return LookUpGlyphBitmap(pFont,
1415 pMatrix,
1416 FaceGlyphsKey,
1417 glyph_index,
1418 bFontStyle,
1419 dest_width,
1420 anti_alias);
1421 #else
1422 if (text_flags & FXTEXT_NO_NATIVETEXT) {
1423 return LookUpGlyphBitmap(pFont,
1424 pMatrix,
1425 FaceGlyphsKey,
1426 glyph_index,
1427 bFontStyle,
1428 dest_width,
1429 anti_alias);
1430 } else {
1431 CFX_GlyphBitmap* pGlyphBitmap;
1055 CFX_SizeGlyphCache* pSizeCache = NULL; 1432 CFX_SizeGlyphCache* pSizeCache = NULL;
1056 while(pos) { 1433 if (m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) {
1057 m_SizeMap.GetNextAssoc( pos, Key, (void*&)pSizeCache); 1434 if (pSizeCache->m_GlyphMap.Lookup((FX_LPVOID)(FX_UINTPTR) glyph_index,
1058 delete pSizeCache; 1435 (void*&)pGlyphBitmap)) {
1059 } 1436 return pGlyphBitmap;
1060 m_SizeMap.RemoveAll(); 1437 }
1061 pos = m_PathMap.GetStartPosition(); 1438 pGlyphBitmap = RenderGlyph_Nativetext(
1062 FX_LPVOID key1; 1439 pFont, glyph_index, pMatrix, dest_width, anti_alias);
1063 CFX_PathData* pPath; 1440 if (pGlyphBitmap) {
1064 while (pos) { 1441 pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR) glyph_index,
1065 m_PathMap.GetNextAssoc(pos, key1, (FX_LPVOID&)pPath); 1442 pGlyphBitmap);
1066 delete pPath; 1443 return pGlyphBitmap;
1067 } 1444 }
1068 if (m_pBitmap) { 1445 } else {
1069 delete m_pBitmap; 1446 pGlyphBitmap = RenderGlyph_Nativetext(
1070 } 1447 pFont, glyph_index, pMatrix, dest_width, anti_alias);
1071 m_PathMap.RemoveAll(); 1448 if (pGlyphBitmap) {
1072 }
1073 #if ((_FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_)|| defined(_FPDFAPI_MINI_))
1074 void CFX_FaceCache::InitPlatform()
1075 {
1076 }
1077 #endif
1078 CFX_GlyphBitmap* CFX_FaceCache::LookUpGlyphBitmap(CFX_Font* pFont, const CFX_Aff ineMatrix* pMatrix,
1079 CFX_ByteStringC& FaceGlyphsKey, FX_DWORD glyph_index, FX_BOOL bFontStyle ,
1080 int dest_width, int anti_alias)
1081 {
1082 CFX_SizeGlyphCache* pSizeCache = NULL;
1083 if (!m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) {
1084 pSizeCache = FX_NEW CFX_SizeGlyphCache; 1449 pSizeCache = FX_NEW CFX_SizeGlyphCache;
1085 if (pSizeCache == NULL)»{ 1450 if (pSizeCache == NULL) {
1086 return NULL; 1451 return NULL;
1087 } 1452 }
1088 m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache); 1453 m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache);
1089 } 1454 pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR) glyph_index,
1090 CFX_GlyphBitmap* pGlyphBitmap = NULL; 1455 pGlyphBitmap);
1091 if (pSizeCache->m_GlyphMap.Lookup((FX_LPVOID)(FX_UINTPTR)glyph_index, (void* &)pGlyphBitmap)) {
1092 return pGlyphBitmap; 1456 return pGlyphBitmap;
1093 } 1457 }
1094 pGlyphBitmap = RenderGlyph(pFont, glyph_index, bFontStyle, pMatrix, dest_wid th, anti_alias); 1458 }
1095 if (pGlyphBitmap == NULL)» {
1096 return NULL;
1097 }
1098 pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR)glyph_index, pGlyphBitma p);
1099 return pGlyphBitmap;
1100 }
1101 const CFX_GlyphBitmap* CFX_FaceCache::LoadGlyphBitmap(CFX_Font* pFont, FX_DWORD glyph_index, FX_BOOL bFontStyle, const CFX_AffineMatrix* pMatrix,
1102 int dest_width, int anti_alias, int& text_flags)
1103 {
1104 if (glyph_index == (FX_DWORD) - 1) {
1105 return NULL;
1106 }
1107 _CFX_UniqueKeyGen keygen;
1108 #if ((_FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_)|| defined(_FPDFAPI_MINI_))
1109 if (pFont->GetSubstFont()) 1459 if (pFont->GetSubstFont())
1110 keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), 1460 keygen.Generate(9,
1111 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), de st_width, anti_alias, 1461 (int)(pMatrix->a * 10000),
1112 pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()-> m_ItalicAngle, pFont->IsVertical()); 1462 (int)(pMatrix->b * 10000),
1463 (int)(pMatrix->c * 10000),
1464 (int)(pMatrix->d * 10000),
1465 dest_width,
1466 anti_alias,
1467 pFont->GetSubstFont()->m_Weight,
1468 pFont->GetSubstFont()->m_ItalicAngle,
1469 pFont->IsVertical());
1113 else 1470 else
1114 keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000), 1471 keygen.Generate(6,
1115 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), de st_width, anti_alias); 1472 (int)(pMatrix->a * 10000),
1473 (int)(pMatrix->b * 10000),
1474 (int)(pMatrix->c * 10000),
1475 (int)(pMatrix->d * 10000),
1476 dest_width,
1477 anti_alias);
1478 CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen);
1479 text_flags |= FXTEXT_NO_NATIVETEXT;
1480 return LookUpGlyphBitmap(pFont,
1481 pMatrix,
1482 FaceGlyphsKey,
1483 glyph_index,
1484 bFontStyle,
1485 dest_width,
1486 anti_alias);
1487 }
1488 #endif
1489 }
1490 CFX_SizeGlyphCache::~CFX_SizeGlyphCache() {
1491 FX_POSITION pos = m_GlyphMap.GetStartPosition();
1492 FX_LPVOID Key;
1493 CFX_GlyphBitmap* pGlyphBitmap = NULL;
1494 while (pos) {
1495 m_GlyphMap.GetNextAssoc(pos, Key, (void*&)pGlyphBitmap);
1496 delete pGlyphBitmap;
1497 }
1498 m_GlyphMap.RemoveAll();
1499 }
1500 #if defined(_FPDFAPI_MINI_)
1501 #define CONTRAST_RAMP_STEP 16
1116 #else 1502 #else
1117 if (text_flags & FXTEXT_NO_NATIVETEXT) { 1503 #define CONTRAST_RAMP_STEP 1
1118 if (pFont->GetSubstFont())
1119 keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 100 00),
1120 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000) , dest_width, anti_alias,
1121 pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont ()->m_ItalicAngle, pFont->IsVertical());
1122 else
1123 keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 100 00),
1124 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000) , dest_width, anti_alias);
1125 } else {
1126 if (pFont->GetSubstFont())
1127 keygen.Generate(10, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10 000),
1128 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000) , dest_width, anti_alias,
1129 pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont ()->m_ItalicAngle, pFont->IsVertical(), 3);
1130 else
1131 keygen.Generate(7, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 100 00),
1132 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000) , dest_width, anti_alias, 3);
1133 }
1134 #endif 1504 #endif
1135 CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen); 1505 void CFX_Font::AdjustMMParams(int glyph_index, int dest_width, int weight) {
1136 #if ((_FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_)|| defined(_FPDFAPI_MINI_)) 1506 FXFT_MM_Var pMasters = NULL;
1137 return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, bFontSt yle, dest_width, anti_alias); 1507 FXFT_Get_MM_Var(m_Face, &pMasters);
1138 #else 1508 if (pMasters == NULL) {
1139 if (text_flags & FXTEXT_NO_NATIVETEXT) { 1509 return;
1140 return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, bFo ntStyle, dest_width, anti_alias); 1510 }
1141 } else { 1511 long coords[2];
1142 CFX_GlyphBitmap* pGlyphBitmap; 1512 if (weight == 0) {
1143 CFX_SizeGlyphCache* pSizeCache = NULL; 1513 coords[0] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 0)) / 65536;
1144 if (m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) { 1514 } else {
1145 if (pSizeCache->m_GlyphMap.Lookup((FX_LPVOID)(FX_UINTPTR)glyph_index , (void*&)pGlyphBitmap)) { 1515 coords[0] = weight;
1146 return pGlyphBitmap; 1516 }
1147 } 1517 if (dest_width == 0) {
1148 pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix, d est_width, anti_alias); 1518 coords[1] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
1149 if (pGlyphBitmap) { 1519 } else {
1150 pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR)glyph_index, pGlyphBitmap); 1520 int min_param = FXFT_Get_MM_Axis_Min(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
1151 return pGlyphBitmap; 1521 int max_param = FXFT_Get_MM_Axis_Max(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
1152 } 1522 coords[1] = min_param;
1153 } else { 1523 int error = FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
1154 pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix, d est_width, anti_alias); 1524 error = FXFT_Load_Glyph(
1155 if (pGlyphBitmap) { 1525 m_Face,
1156 pSizeCache = FX_NEW CFX_SizeGlyphCache; 1526 glyph_index,
1157 if (pSizeCache == NULL)»{ 1527 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
1158 return NULL; 1528 int min_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 /
1159 } 1529 FXFT_Get_Face_UnitsPerEM(m_Face);
1160 m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache); 1530 coords[1] = max_param;
1161 pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR)glyph_index, pGlyphBitmap); 1531 error = FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
1162 return pGlyphBitmap; 1532 error = FXFT_Load_Glyph(
1163 } 1533 m_Face,
1164 } 1534 glyph_index,
1165 if (pFont->GetSubstFont()) 1535 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
1166 keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 100 00), 1536 int max_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 /
1167 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000) , dest_width, anti_alias, 1537 FXFT_Get_Face_UnitsPerEM(m_Face);
1168 pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont ()->m_ItalicAngle, pFont->IsVertical()); 1538 if (max_width == min_width) {
1169 else 1539 return;
1170 keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 100 00), 1540 }
1171 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000) , dest_width, anti_alias); 1541 int param = min_param +
1172 CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen); 1542 (max_param - min_param) * (dest_width - min_width) /
1173 text_flags |= FXTEXT_NO_NATIVETEXT; 1543 (max_width - min_width);
1174 return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, bFo ntStyle, dest_width, anti_alias); 1544 coords[1] = param;
1175 } 1545 }
1176 #endif 1546 FXFT_Free(m_Face, pMasters);
1177 } 1547 FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
1178 CFX_SizeGlyphCache::~CFX_SizeGlyphCache()
1179 {
1180 FX_POSITION pos = m_GlyphMap.GetStartPosition();
1181 FX_LPVOID Key;
1182 CFX_GlyphBitmap* pGlyphBitmap = NULL;
1183 while(pos) {
1184 m_GlyphMap.GetNextAssoc(pos, Key, (void*&)pGlyphBitmap);
1185 delete pGlyphBitmap;
1186 }
1187 m_GlyphMap.RemoveAll();
1188 }
1189 #if defined(_FPDFAPI_MINI_)
1190 #define CONTRAST_RAMP_STEP» 16
1191 #else
1192 #define CONTRAST_RAMP_STEP» 1
1193 #endif
1194 void CFX_Font::AdjustMMParams(int glyph_index, int dest_width, int weight)
1195 {
1196 FXFT_MM_Var pMasters = NULL;
1197 FXFT_Get_MM_Var(m_Face, &pMasters);
1198 if (pMasters == NULL) {
1199 return;
1200 }
1201 long coords[2];
1202 if (weight == 0) {
1203 coords[0] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 0)) / 65536;
1204 } else {
1205 coords[0] = weight;
1206 }
1207 if (dest_width == 0) {
1208 coords[1] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
1209 } else {
1210 int min_param = FXFT_Get_MM_Axis_Min(FXFT_Get_MM_Axis(pMasters, 1)) / 65 536;
1211 int max_param = FXFT_Get_MM_Axis_Max(FXFT_Get_MM_Axis(pMasters, 1)) / 65 536;
1212 coords[1] = min_param;
1213 int error = FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
1214 error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_L OAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
1215 int min_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / FXFT_Get_Fac e_UnitsPerEM(m_Face);
1216 coords[1] = max_param;
1217 error = FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
1218 error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_L OAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
1219 int max_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / FXFT_Get_Fac e_UnitsPerEM(m_Face);
1220 if (max_width == min_width) {
1221 return;
1222 }
1223 int param = min_param + (max_param - min_param) * (dest_width - min_widt h) / (max_width - min_width);
1224 coords[1] = param;
1225 }
1226 FXFT_Free(m_Face, pMasters);
1227 FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
1228 } 1548 }
1229 extern const char g_AngleSkew[30] = { 1549 extern const char g_AngleSkew[30] = {
1230 0, 2, 3, 5, 7, 9, 11, 12, 14, 16, 1550 0, 2, 3, 5, 7, 9, 11, 12, 14, 16, 18, 19, 21, 23, 25,
1231 18, 19, 21, 23, 25, 27, 29, 31, 32, 34, 1551 27, 29, 31, 32, 34, 36, 38, 40, 42, 45, 47, 49, 51, 53, 55,
1232 36, 38, 40, 42, 45, 47, 49, 51, 53, 55,
1233 }; 1552 };
1234 static const FX_BYTE g_WeightPow[100] = { 1553 static const FX_BYTE g_WeightPow[100] = {
1235 0, 3, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19, 20, 1554 0, 3, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22,
1236 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 36, 1555 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 36, 37,
1237 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 1556 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42,
1238 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 1557 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47,
1239 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51, 1558 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50,
1240 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 1559 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53,
1241 }; 1560 };
1242 extern const FX_BYTE g_WeightPow_11[100] = { 1561 extern const FX_BYTE g_WeightPow_11[100] = {
1243 0, 4, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22, 1562 0, 4, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 24,
1244 23, 24, 25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40, 1563 25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40, 41,
1245 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46, 1564 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46,
1246 46, 43, 47, 47, 48, 48, 48, 48, 45, 50, 50, 50, 46, 51, 51, 51, 52, 52, 1565 46, 43, 47, 47, 48, 48, 48, 48, 45, 50, 50, 50, 46, 51, 51, 51, 52,
1247 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 1566 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55,
1248 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 1567 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58,
1249 }; 1568 };
1250 extern const FX_BYTE g_WeightPow_SHIFTJIS[100] = { 1569 extern const FX_BYTE g_WeightPow_SHIFTJIS[100] = {
1251 0, 0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 21, 22, 24, 26, 28, 1570 0, 0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 21,
1252 30, 32, 33, 35, 37, 39, 41, 43, 45, 48, 48, 48, 48, 49, 49, 49, 50, 50, 50, 50, 1571 22, 24, 26, 28, 30, 32, 33, 35, 37, 39, 41, 43, 45, 48, 48, 48, 48,
1253 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 1572 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53,
1254 55, 55, 55, 56, 56, 56, 56, 56 , 56, 57, 57, 57 , 57 , 57, 57, 57, 58, 58, 5 8, 58, 58, 1573 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56,
1255 58, 58, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 1574 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58,
1575 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60,
1256 }; 1576 };
1257 static void _GammaAdjust(FX_LPBYTE pData, int nWid, int nHei, int src_pitch, FX_ LPCBYTE gammaTable) 1577 static void _GammaAdjust(FX_LPBYTE pData,
1258 { 1578 int nWid,
1259 int count = nHei * src_pitch; 1579 int nHei,
1260 for(int i = 0; i < count; i++) { 1580 int src_pitch,
1261 pData[i] = gammaTable[pData[i]]; 1581 FX_LPCBYTE gammaTable) {
1262 } 1582 int count = nHei * src_pitch;
1263 } 1583 for (int i = 0; i < count; i++) {
1264 static void _ContrastAdjust(FX_LPBYTE pDataIn, FX_LPBYTE pDataOut, int nWid, int nHei, int nSrcRowBytes, int nDstRowBytes) 1584 pData[i] = gammaTable[pData[i]];
1265 { 1585 }
1266 int col, row, temp; 1586 }
1267 int max = 0, min = 255; 1587 static void _ContrastAdjust(FX_LPBYTE pDataIn,
1268 FX_FLOAT rate; 1588 FX_LPBYTE pDataOut,
1269 for (row = 0; row < nHei; row ++) { 1589 int nWid,
1270 FX_LPBYTE pRow = pDataIn + row * nSrcRowBytes; 1590 int nHei,
1271 for (col = 0; col < nWid; col++) { 1591 int nSrcRowBytes,
1272 temp = *pRow ++; 1592 int nDstRowBytes) {
1273 if (temp > max) { 1593 int col, row, temp;
1274 max = temp; 1594 int max = 0, min = 255;
1275 } 1595 FX_FLOAT rate;
1276 if (temp < min) { 1596 for (row = 0; row < nHei; row++) {
1277 min = temp; 1597 FX_LPBYTE pRow = pDataIn + row * nSrcRowBytes;
1278 } 1598 for (col = 0; col < nWid; col++) {
1599 temp = *pRow++;
1600 if (temp > max) {
1601 max = temp;
1602 }
1603 if (temp < min) {
1604 min = temp;
1605 }
1606 }
1607 }
1608 temp = max - min;
1609 if (0 == temp || 255 == temp) {
1610 int rowbytes = FXSYS_abs(nSrcRowBytes) > nDstRowBytes
1611 ? nDstRowBytes
1612 : FXSYS_abs(nSrcRowBytes);
1613 for (row = 0; row < nHei; row++) {
1614 FXSYS_memcpy32(pDataOut + row * nDstRowBytes,
1615 pDataIn + row * nSrcRowBytes,
1616 rowbytes);
1617 }
1618 return;
1619 }
1620 rate = 255.f / temp;
1621 for (row = 0; row < nHei; row++) {
1622 FX_LPBYTE pSrcRow = pDataIn + row * nSrcRowBytes;
1623 FX_LPBYTE pDstRow = pDataOut + row * nDstRowBytes;
1624 for (col = 0; col < nWid; col++) {
1625 temp = (int)((*(pSrcRow++) - min) * rate + 0.5);
1626 if (temp > 255) {
1627 temp = 255;
1628 } else if (temp < 0) {
1629 temp = 0;
1630 }
1631 *pDstRow++ = (FX_BYTE)temp;
1632 }
1633 }
1634 }
1635 CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph(CFX_Font* pFont,
1636 FX_DWORD glyph_index,
1637 FX_BOOL bFontStyle,
1638 const CFX_AffineMatrix* pMatrix,
1639 int dest_width,
1640 int anti_alias) {
1641 if (m_Face == NULL) {
1642 return NULL;
1643 }
1644 FXFT_Matrix ft_matrix;
1645 ft_matrix.xx = (signed long)(pMatrix->GetA() / 64 * 65536);
1646 ft_matrix.xy = (signed long)(pMatrix->GetC() / 64 * 65536);
1647 ft_matrix.yx = (signed long)(pMatrix->GetB() / 64 * 65536);
1648 ft_matrix.yy = (signed long)(pMatrix->GetD() / 64 * 65536);
1649 FX_BOOL bUseCJKSubFont = FALSE;
1650 const CFX_SubstFont* pSubstFont = pFont->GetSubstFont();
1651 if (pSubstFont) {
1652 bUseCJKSubFont = pSubstFont->m_bSubstOfCJK && bFontStyle;
1653 int skew = 0;
1654 if (bUseCJKSubFont) {
1655 skew = pSubstFont->m_bItlicCJK ? -15 : 0;
1656 } else {
1657 skew = pSubstFont->m_ItalicAngle;
1658 }
1659 if (skew) {
1660 skew = skew <= -30 ? -58 : -g_AngleSkew[-skew];
1661 if (pFont->IsVertical()) {
1662 ft_matrix.yx += ft_matrix.yy * skew / 100;
1663 } else {
1664 ft_matrix.xy += -ft_matrix.xx * skew / 100;
1665 }
1666 }
1667 if (pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) {
1668 pFont->AdjustMMParams(
1669 glyph_index, dest_width, pFont->GetSubstFont()->m_Weight);
1670 }
1671 }
1672 int transflag = FXFT_Get_Face_Internal_Flag(m_Face);
1673 FXFT_Set_Transform(m_Face, &ft_matrix, 0);
1674 int load_flags = (m_Face->face_flags & FT_FACE_FLAG_SFNT)
1675 ? FXFT_LOAD_NO_BITMAP
1676 : (FXFT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
1677 int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags);
1678 if (error) {
1679 FXFT_Set_Face_Internal_Flag(m_Face, transflag);
1680 return NULL;
1681 }
1682 int weight = 0;
1683 if (bUseCJKSubFont) {
1684 weight = pSubstFont->m_WeightCJK;
1685 } else {
1686 weight = pSubstFont ? pSubstFont->m_Weight : 0;
1687 }
1688 if (pSubstFont && !(pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) &&
1689 weight > 400) {
1690 int index = (weight - 400) / 10;
1691 if (index >= 100) {
1692 FXFT_Set_Face_Internal_Flag(m_Face, transflag);
1693 return NULL;
1694 }
1695 int level = 0;
1696 if (pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) {
1697 level =
1698 g_WeightPow_SHIFTJIS[index] * 2 *
1699 (FXSYS_abs((int)(ft_matrix.xx)) + FXSYS_abs((int)(ft_matrix.xy))) /
1700 36655;
1701 } else {
1702 level = g_WeightPow_11[index] * (FXSYS_abs((int)(ft_matrix.xx)) +
1703 FXSYS_abs((int)(ft_matrix.xy))) /
1704 36655;
1705 }
1706 FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level);
1707 }
1708 FXFT_Library_SetLcdFilter(CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary,
1709 FT_LCD_FILTER_DEFAULT);
1710 error = FXFT_Render_Glyph(m_Face, anti_alias);
1711 if (error) {
1712 FXFT_Set_Face_Internal_Flag(m_Face, transflag);
1713 return NULL;
1714 }
1715 int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(m_Face));
1716 int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(m_Face));
1717 if (bmwidth > 2048 || bmheight > 2048) {
1718 FXFT_Set_Face_Internal_Flag(m_Face, transflag);
1719 return NULL;
1720 }
1721 int dib_width = bmwidth;
1722 CFX_GlyphBitmap* pGlyphBitmap = FX_NEW CFX_GlyphBitmap;
1723 if (!pGlyphBitmap) {
1724 return NULL;
1725 }
1726 pGlyphBitmap->m_Bitmap.Create(
1727 dib_width,
1728 bmheight,
1729 anti_alias == FXFT_RENDER_MODE_MONO ? FXDIB_1bppMask : FXDIB_8bppMask);
1730 pGlyphBitmap->m_Left = FXFT_Get_Glyph_BitmapLeft(m_Face);
1731 pGlyphBitmap->m_Top = FXFT_Get_Glyph_BitmapTop(m_Face);
1732 int dest_pitch = pGlyphBitmap->m_Bitmap.GetPitch();
1733 int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(m_Face));
1734 FX_BYTE* pDestBuf = pGlyphBitmap->m_Bitmap.GetBuffer();
1735 FX_BYTE* pSrcBuf =
1736 (FX_BYTE*)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(m_Face));
1737 if (anti_alias != FXFT_RENDER_MODE_MONO &&
1738 FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) ==
1739 FXFT_PIXEL_MODE_MONO) {
1740 int bytes = anti_alias == FXFT_RENDER_MODE_LCD ? 3 : 1;
1741 for (int i = 0; i < bmheight; i++)
1742 for (int n = 0; n < bmwidth; n++) {
1743 FX_BYTE data =
1744 (pSrcBuf[i * src_pitch + n / 8] & (0x80 >> (n % 8))) ? 255 : 0;
1745 for (int b = 0; b < bytes; b++) {
1746 pDestBuf[i * dest_pitch + n * bytes + b] = data;
1279 } 1747 }
1280 } 1748 }
1281 temp = max - min; 1749 } else {
1282 if (0 == temp || 255 == temp) { 1750 FXSYS_memset32(pDestBuf, 0, dest_pitch * bmheight);
1283 int rowbytes = FXSYS_abs(nSrcRowBytes) > nDstRowBytes ? nDstRowBytes : F XSYS_abs(nSrcRowBytes); 1751 if (anti_alias == FXFT_RENDER_MODE_MONO &&
1284 for (row = 0; row < nHei; row ++) { 1752 FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) ==
1285 FXSYS_memcpy32(pDataOut + row * nDstRowBytes, pDataIn + row * nSrcRo wBytes, rowbytes); 1753 FXFT_PIXEL_MODE_MONO) {
1286 } 1754 int rowbytes =
1287 return; 1755 FXSYS_abs(src_pitch) > dest_pitch ? dest_pitch : FXSYS_abs(src_pitch);
1288 } 1756 for (int row = 0; row < bmheight; row++) {
1289 rate = 255.f / temp; 1757 FXSYS_memcpy32(
1290 for (row = 0; row < nHei; row ++) { 1758 pDestBuf + row * dest_pitch, pSrcBuf + row * src_pitch, rowbytes);
1291 FX_LPBYTE pSrcRow = pDataIn + row * nSrcRowBytes; 1759 }
1292 FX_LPBYTE pDstRow = pDataOut + row * nDstRowBytes;
1293 for (col = 0; col < nWid; col ++) {
1294 temp = (int)((*(pSrcRow++) - min) * rate + 0.5);
1295 if (temp > 255)» {
1296 temp = 255;
1297 } else if (temp < 0) {
1298 temp = 0;
1299 }
1300 *pDstRow ++ = (FX_BYTE)temp;
1301 }
1302 }
1303 }
1304 CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph(CFX_Font* pFont, FX_DWORD glyph_inde x, FX_BOOL bFontStyle,
1305 const CFX_AffineMatrix* pMatrix, int dest_width, int anti_alias)
1306 {
1307 if (m_Face == NULL) {
1308 return NULL;
1309 }
1310 FXFT_Matrix ft_matrix;
1311 ft_matrix.xx = (signed long)(pMatrix->GetA() / 64 * 65536);
1312 ft_matrix.xy = (signed long)(pMatrix->GetC() / 64 * 65536);
1313 ft_matrix.yx = (signed long)(pMatrix->GetB() / 64 * 65536);
1314 ft_matrix.yy = (signed long)(pMatrix->GetD() / 64 * 65536);
1315 FX_BOOL bUseCJKSubFont = FALSE;
1316 const CFX_SubstFont* pSubstFont = pFont->GetSubstFont();
1317 if (pSubstFont) {
1318 bUseCJKSubFont = pSubstFont->m_bSubstOfCJK && bFontStyle;
1319 int skew = 0;
1320 if (bUseCJKSubFont) {
1321 skew = pSubstFont->m_bItlicCJK ? -15 : 0;
1322 } else {
1323 skew = pSubstFont->m_ItalicAngle;
1324 }
1325 if (skew) {
1326 skew = skew <= -30 ? -58 : -g_AngleSkew[-skew];
1327 if (pFont->IsVertical()) {
1328 ft_matrix.yx += ft_matrix.yy * skew / 100;
1329 } else {
1330 ft_matrix.xy += -ft_matrix.xx * skew / 100;
1331 }
1332 }
1333 if (pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) {
1334 pFont->AdjustMMParams(glyph_index, dest_width, pFont->GetSubstFont() ->m_Weight);
1335 }
1336 }
1337 int transflag = FXFT_Get_Face_Internal_Flag(m_Face);
1338 FXFT_Set_Transform(m_Face, &ft_matrix, 0);
1339 int load_flags = (m_Face->face_flags & FT_FACE_FLAG_SFNT) ? FXFT_LOAD_NO_BIT MAP : (FXFT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
1340 int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags);
1341 if (error) {
1342 FXFT_Set_Face_Internal_Flag(m_Face, transflag);
1343 return NULL;
1344 }
1345 int weight = 0;
1346 if (bUseCJKSubFont) {
1347 weight = pSubstFont->m_WeightCJK;
1348 } else { 1760 } else {
1349 weight = pSubstFont ? pSubstFont->m_Weight : 0; 1761 _ContrastAdjust(
1350 } 1762 pSrcBuf, pDestBuf, bmwidth, bmheight, src_pitch, dest_pitch);
1351 if (pSubstFont && !(pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && weight > 400) { 1763 _GammaAdjust(pDestBuf,
1352 int index = (weight - 400) / 10; 1764 bmwidth,
1353 if (index >= 100) { 1765 bmheight,
1354 FXFT_Set_Face_Internal_Flag(m_Face, transflag); 1766 dest_pitch,
1355 return NULL; 1767 CFX_GEModule::Get()->GetTextGammaTable());
1356 } 1768 }
1357 int level = 0; 1769 }
1358 if (pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) { 1770 FXFT_Set_Face_Internal_Flag(m_Face, transflag);
1359 level = g_WeightPow_SHIFTJIS[index] * 2 * (FXSYS_abs((int)(ft_matrix .xx)) + FXSYS_abs((int)(ft_matrix.xy))) / 36655; 1771 return pGlyphBitmap;
1360 } else { 1772 }
1361 level = g_WeightPow_11[index] * (FXSYS_abs((int)(ft_matrix.xx)) + FX SYS_abs((int)(ft_matrix.xy))) / 36655; 1773 FX_BOOL _OutputGlyph(void* dib,
1362 } 1774 int x,
1363 FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level); 1775 int y,
1364 } 1776 CFX_Font* pFont,
1365 FXFT_Library_SetLcdFilter(CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary, FT _LCD_FILTER_DEFAULT); 1777 int glyph_index,
1366 error = FXFT_Render_Glyph(m_Face, anti_alias); 1778 FX_ARGB argb) {
1367 if (error) { 1779 CFX_DIBitmap* pDib = (CFX_DIBitmap*)dib;
1368 FXFT_Set_Face_Internal_Flag(m_Face, transflag); 1780 FXFT_Face face = pFont->GetFace();
1369 return NULL; 1781 int error = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_BITMAP);
1370 } 1782 if (error) {
1371 int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(m_Face)); 1783 return FALSE;
1372 int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(m_Face)); 1784 }
1373 if (bmwidth > 2048 || bmheight > 2048) { 1785 error = FXFT_Render_Glyph(face, FXFT_RENDER_MODE_NORMAL);
1374 FXFT_Set_Face_Internal_Flag(m_Face, transflag); 1786 if (error) {
1375 return NULL; 1787 return FALSE;
1376 } 1788 }
1377 int dib_width = bmwidth; 1789 int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(face));
1378 CFX_GlyphBitmap* pGlyphBitmap = FX_NEW CFX_GlyphBitmap; 1790 int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(face));
1379 if (!pGlyphBitmap) { 1791 int left = FXFT_Get_Glyph_BitmapLeft(face);
1380 return NULL; 1792 int top = FXFT_Get_Glyph_BitmapTop(face);
1381 } 1793 FX_LPCBYTE src_buf =
1382 pGlyphBitmap->m_Bitmap.Create(dib_width, bmheight, 1794 (FX_LPCBYTE)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(face));
1383 anti_alias == FXFT_RENDER_MODE_MONO ? FXDIB_1b ppMask : FXDIB_8bppMask); 1795 int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(face));
1384 pGlyphBitmap->m_Left = FXFT_Get_Glyph_BitmapLeft(m_Face); 1796 CFX_DIBitmap mask;
1385 pGlyphBitmap->m_Top = FXFT_Get_Glyph_BitmapTop(m_Face); 1797 mask.Create(bmwidth, bmheight, FXDIB_8bppMask);
1386 int dest_pitch = pGlyphBitmap->m_Bitmap.GetPitch(); 1798 FX_LPBYTE dest_buf = mask.GetBuffer();
1387 int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(m_Face)); 1799 int dest_pitch = mask.GetPitch();
1388 FX_BYTE* pDestBuf = pGlyphBitmap->m_Bitmap.GetBuffer(); 1800 for (int row = 0; row < bmheight; row++) {
1389 FX_BYTE* pSrcBuf = (FX_BYTE*)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(m_ Face)); 1801 FX_LPCBYTE src_scan = src_buf + row * src_pitch;
1390 if (anti_alias != FXFT_RENDER_MODE_MONO && FXFT_Get_Bitmap_PixelMode(FXFT_Ge t_Glyph_Bitmap(m_Face)) == FXFT_PIXEL_MODE_MONO) { 1802 FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
1391 int bytes = anti_alias == FXFT_RENDER_MODE_LCD ? 3 : 1; 1803 FXSYS_memcpy32(dest_scan, src_scan, dest_pitch);
1392 for(int i = 0; i < bmheight; i++) 1804 }
1393 for(int n = 0; n < bmwidth; n++) { 1805 pDib->CompositeMask(x + left, y - top, bmwidth, bmheight, &mask, argb, 0, 0);
1394 FX_BYTE data = (pSrcBuf[i * src_pitch + n / 8] & (0x80 >> (n % 8 ))) ? 255 : 0; 1806 return TRUE;
1395 for (int b = 0; b < bytes; b ++) { 1807 }
1396 pDestBuf[i * dest_pitch + n * bytes + b] = data; 1808 FX_BOOL OutputText(void* dib,
1397 } 1809 int x,
1398 } 1810 int y,
1399 } else { 1811 CFX_Font* pFont,
1400 FXSYS_memset32(pDestBuf, 0, dest_pitch * bmheight); 1812 double font_size,
1401 if (anti_alias == FXFT_RENDER_MODE_MONO && FXFT_Get_Bitmap_PixelMode(FXF T_Get_Glyph_Bitmap(m_Face)) == FXFT_PIXEL_MODE_MONO) { 1813 CFX_AffineMatrix* pText_matrix,
1402 int rowbytes = FXSYS_abs(src_pitch) > dest_pitch ? dest_pitch : FXSY S_abs(src_pitch); 1814 unsigned short const* text,
1403 for (int row = 0; row < bmheight; row ++) { 1815 unsigned long argb) {
1404 FXSYS_memcpy32(pDestBuf + row * dest_pitch, pSrcBuf + row * src_ pitch, rowbytes); 1816 if (!pFont) {
1405 } 1817 return FALSE;
1406 } else { 1818 }
1407 _ContrastAdjust(pSrcBuf, pDestBuf, bmwidth, bmheight, src_pitch, des t_pitch); 1819 FXFT_Face face = pFont->GetFace();
1408 _GammaAdjust(pDestBuf, bmwidth, bmheight, dest_pitch, CFX_GEModule:: Get()->GetTextGammaTable()); 1820 FXFT_Select_Charmap(pFont->m_Face, FXFT_ENCODING_UNICODE);
1409 } 1821 int transflag = FXFT_Get_Face_Internal_Flag(pFont->m_Face);
1410 } 1822 if (pText_matrix) {
1411 FXFT_Set_Face_Internal_Flag(m_Face, transflag); 1823 FXFT_Matrix ft_matrix;
1412 return pGlyphBitmap; 1824 ft_matrix.xx = (signed long)(pText_matrix->a / 64 * 65536);
1413 } 1825 ft_matrix.xy = (signed long)(pText_matrix->c / 64 * 65536);
1414 FX_BOOL _OutputGlyph(void* dib, int x, int y, CFX_Font* pFont, 1826 ft_matrix.yx = (signed long)(pText_matrix->b / 64 * 65536);
1415 int glyph_index, FX_ARGB argb) 1827 ft_matrix.yy = (signed long)(pText_matrix->d / 64 * 65536);
1416 { 1828 FXFT_Set_Transform(face, &ft_matrix, 0);
1417 CFX_DIBitmap* pDib = (CFX_DIBitmap*)dib; 1829 }
1418 FXFT_Face face = pFont->GetFace(); 1830 FX_FLOAT x_pos = 0;
1419 int error = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_BITMAP); 1831 for (; *text != 0; text++) {
1420 if (error) { 1832 FX_WCHAR unicode = *text;
1421 return FALSE; 1833 int glyph_index = FXFT_Get_Char_Index(pFont->m_Face, unicode);
1422 } 1834 if (glyph_index <= 0) {
1423 error = FXFT_Render_Glyph(face, FXFT_RENDER_MODE_NORMAL); 1835 continue;
1424 if (error) { 1836 }
1425 return FALSE; 1837 int err = FXFT_Load_Glyph(
1426 } 1838 pFont->m_Face,
1427 int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(face)); 1839 glyph_index,
1428 int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(face)); 1840 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
1429 int left = FXFT_Get_Glyph_BitmapLeft(face); 1841 if (err) {
1430 int top = FXFT_Get_Glyph_BitmapTop(face); 1842 continue;
1431 FX_LPCBYTE src_buf = (FX_LPCBYTE)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitma p(face)); 1843 }
1432 int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(face)); 1844 int w = FXFT_Get_Glyph_HoriAdvance(pFont->m_Face);
1433 CFX_DIBitmap mask; 1845 int em = FXFT_Get_Face_UnitsPerEM(pFont->m_Face);
1434 mask.Create(bmwidth, bmheight, FXDIB_8bppMask); 1846 FX_FLOAT x1, y1;
1435 FX_LPBYTE dest_buf = mask.GetBuffer(); 1847 pText_matrix->Transform(x_pos, 0, x1, y1);
1436 int dest_pitch = mask.GetPitch(); 1848 _OutputGlyph(dib, (int)x1 + x, (int)-y1 + y, pFont, glyph_index, argb);
1437 for (int row = 0; row < bmheight; row ++) { 1849 x_pos += (FX_FLOAT)w / em;
1438 FX_LPCBYTE src_scan = src_buf + row * src_pitch; 1850 }
1439 FX_LPBYTE dest_scan = dest_buf + row * dest_pitch; 1851 FXFT_Set_Face_Internal_Flag(pFont->m_Face, transflag);
1440 FXSYS_memcpy32(dest_scan, src_scan, dest_pitch); 1852 return TRUE;
1441 } 1853 }
1442 pDib->CompositeMask(x + left, y - top, bmwidth, bmheight, &mask, argb, 0, 0) ; 1854 FX_BOOL OutputGlyph(void* dib,
1443 return TRUE; 1855 int x,
1444 } 1856 int y,
1445 FX_BOOL OutputText(void* dib, int x, int y, CFX_Font* pFont, double font_size, 1857 CFX_Font* pFont,
1446 CFX_AffineMatrix* pText_matrix, unsigned short const* text, u nsigned long argb) 1858 double font_size,
1447 { 1859 CFX_AffineMatrix* pMatrix,
1448 if (!pFont) { 1860 unsigned long glyph_index,
1449 return FALSE; 1861 unsigned long argb) {
1450 } 1862 FXFT_Matrix ft_matrix;
1451 FXFT_Face face = pFont->GetFace(); 1863 if (pMatrix) {
1452 FXFT_Select_Charmap(pFont->m_Face, FXFT_ENCODING_UNICODE); 1864 ft_matrix.xx = (signed long)(pMatrix->a * font_size / 64 * 65536);
1453 int transflag = FXFT_Get_Face_Internal_Flag(pFont->m_Face); 1865 ft_matrix.xy = (signed long)(pMatrix->c * font_size / 64 * 65536);
1454 if (pText_matrix) { 1866 ft_matrix.yx = (signed long)(pMatrix->b * font_size / 64 * 65536);
1455 FXFT_Matrix ft_matrix; 1867 ft_matrix.yy = (signed long)(pMatrix->d * font_size / 64 * 65536);
1456 ft_matrix.xx = (signed long)(pText_matrix->a / 64 * 65536); 1868 } else {
1457 ft_matrix.xy = (signed long)(pText_matrix->c / 64 * 65536); 1869 ft_matrix.xx = (signed long)(font_size / 64 * 65536);
1458 ft_matrix.yx = (signed long)(pText_matrix->b / 64 * 65536); 1870 ft_matrix.xy = ft_matrix.yx = 0;
1459 ft_matrix.yy = (signed long)(pText_matrix->d / 64 * 65536); 1871 ft_matrix.yy = (signed long)(font_size / 64 * 65536);
1460 FXFT_Set_Transform(face, &ft_matrix, 0); 1872 }
1461 } 1873 int transflag = FXFT_Get_Face_Internal_Flag(pFont->m_Face);
1462 FX_FLOAT x_pos = 0; 1874 FXFT_Set_Transform(pFont->m_Face, &ft_matrix, 0);
1463 for (; *text != 0; text ++) { 1875 FX_BOOL ret = _OutputGlyph(dib, x, y, pFont, glyph_index, argb);
1464 FX_WCHAR unicode = *text; 1876 FXFT_Set_Face_Internal_Flag(pFont->m_Face, transflag);
1465 int glyph_index = FXFT_Get_Char_Index(pFont->m_Face, unicode); 1877 return ret;
1466 if (glyph_index <= 0) { 1878 }
1467 continue; 1879 const CFX_PathData* CFX_FaceCache::LoadGlyphPath(CFX_Font* pFont,
1468 } 1880 FX_DWORD glyph_index,
1469 int err = FXFT_Load_Glyph(pFont->m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); 1881 int dest_width) {
1470 if (err) { 1882 if (m_Face == NULL || glyph_index == (FX_DWORD)-1) {
1471 continue; 1883 return NULL;
1472 } 1884 }
1473 int w = FXFT_Get_Glyph_HoriAdvance(pFont->m_Face); 1885 CFX_PathData* pGlyphPath = NULL;
1474 int em = FXFT_Get_Face_UnitsPerEM(pFont->m_Face); 1886 FX_LPVOID key;
1475 FX_FLOAT x1, y1; 1887 if (pFont->GetSubstFont())
1476 pText_matrix->Transform(x_pos, 0, x1, y1); 1888 key = (FX_LPVOID)(FX_UINTPTR)(
1477 _OutputGlyph(dib, (int)x1 + x, (int) - y1 + y, pFont, 1889 glyph_index + ((pFont->GetSubstFont()->m_Weight / 16) << 15) +
1478 glyph_index, argb); 1890 ((pFont->GetSubstFont()->m_ItalicAngle / 2) << 21) +
1479 x_pos += (FX_FLOAT)w / em; 1891 ((dest_width / 16) << 25) + (pFont->IsVertical() << 31));
1480 } 1892 else {
1481 FXFT_Set_Face_Internal_Flag(pFont->m_Face, transflag); 1893 key = (FX_LPVOID)(FX_UINTPTR) glyph_index;
1482 return TRUE; 1894 }
1483 } 1895 if (m_PathMap.Lookup(key, (FX_LPVOID&)pGlyphPath)) {
1484 FX_BOOL OutputGlyph(void* dib, int x, int y, CFX_Font* pFont, double font_size,
1485 CFX_AffineMatrix* pMatrix, unsigned long glyph_index, unsign ed long argb)
1486 {
1487 FXFT_Matrix ft_matrix;
1488 if (pMatrix) {
1489 ft_matrix.xx = (signed long)(pMatrix->a * font_size / 64 * 65536);
1490 ft_matrix.xy = (signed long)(pMatrix->c * font_size / 64 * 65536);
1491 ft_matrix.yx = (signed long)(pMatrix->b * font_size / 64 * 65536);
1492 ft_matrix.yy = (signed long)(pMatrix->d * font_size / 64 * 65536);
1493 } else {
1494 ft_matrix.xx = (signed long)(font_size / 64 * 65536);
1495 ft_matrix.xy = ft_matrix.yx = 0;
1496 ft_matrix.yy = (signed long)(font_size / 64 * 65536);
1497 }
1498 int transflag = FXFT_Get_Face_Internal_Flag(pFont->m_Face);
1499 FXFT_Set_Transform(pFont->m_Face, &ft_matrix, 0);
1500 FX_BOOL ret = _OutputGlyph(dib, x, y, pFont,
1501 glyph_index, argb);
1502 FXFT_Set_Face_Internal_Flag(pFont->m_Face, transflag);
1503 return ret;
1504 }
1505 const CFX_PathData* CFX_FaceCache::LoadGlyphPath(CFX_Font* pFont, FX_DWORD glyph _index, int dest_width)
1506 {
1507 if (m_Face == NULL || glyph_index == (FX_DWORD) - 1) {
1508 return NULL;
1509 }
1510 CFX_PathData* pGlyphPath = NULL;
1511 FX_LPVOID key;
1512 if (pFont->GetSubstFont())
1513 key = (FX_LPVOID)(FX_UINTPTR)(glyph_index + ((pFont->GetSubstFont()->m_W eight / 16) << 15) +
1514 ((pFont->GetSubstFont()->m_ItalicAngle / 2 ) << 21) + ((dest_width / 16) << 25) +
1515 (pFont->IsVertical() << 31));
1516 else {
1517 key = (FX_LPVOID)(FX_UINTPTR)glyph_index;
1518 }
1519 if (m_PathMap.Lookup(key, (FX_LPVOID&)pGlyphPath)) {
1520 return pGlyphPath;
1521 }
1522 pGlyphPath = pFont->LoadGlyphPath(glyph_index, dest_width);
1523 m_PathMap.SetAt(key, pGlyphPath);
1524 return pGlyphPath; 1896 return pGlyphPath;
1897 }
1898 pGlyphPath = pFont->LoadGlyphPath(glyph_index, dest_width);
1899 m_PathMap.SetAt(key, pGlyphPath);
1900 return pGlyphPath;
1525 } 1901 }
1526 typedef struct { 1902 typedef struct {
1527 FX_BOOL» » » m_bCount; 1903 FX_BOOL m_bCount;
1528 int»» » » m_PointCount; 1904 int m_PointCount;
1529 FX_PATHPOINT*» m_pPoints; 1905 FX_PATHPOINT* m_pPoints;
1530 int»» » » m_CurX; 1906 int m_CurX;
1531 int»» » » m_CurY; 1907 int m_CurY;
1532 FX_FLOAT» » m_CoordUnit; 1908 FX_FLOAT m_CoordUnit;
1533 } OUTLINE_PARAMS; 1909 } OUTLINE_PARAMS;
1534 void _Outline_CheckEmptyContour(OUTLINE_PARAMS* param) 1910 void _Outline_CheckEmptyContour(OUTLINE_PARAMS* param) {
1535 { 1911 if (param->m_PointCount >= 2 &&
1536 if (param->m_PointCount >= 2 && param->m_pPoints[param->m_PointCount - 2].m_ Flag == FXPT_MOVETO && 1912 param->m_pPoints[param->m_PointCount - 2].m_Flag == FXPT_MOVETO &&
1537 param->m_pPoints[param->m_PointCount - 2].m_PointX == param->m_pPoin ts[param->m_PointCount - 1].m_PointX && 1913 param->m_pPoints[param->m_PointCount - 2].m_PointX ==
1538 param->m_pPoints[param->m_PointCount - 2].m_PointY == param->m_pPoin ts[param->m_PointCount - 1].m_PointY) { 1914 param->m_pPoints[param->m_PointCount - 1].m_PointX &&
1539 param->m_PointCount -= 2; 1915 param->m_pPoints[param->m_PointCount - 2].m_PointY ==
1540 } 1916 param->m_pPoints[param->m_PointCount - 1].m_PointY) {
1541 if (param->m_PointCount >= 4 && param->m_pPoints[param->m_PointCount - 4].m_ Flag == FXPT_MOVETO && 1917 param->m_PointCount -= 2;
1542 param->m_pPoints[param->m_PointCount - 3].m_Flag == FXPT_BEZIERTO && 1918 }
1543 param->m_pPoints[param->m_PointCount - 3].m_PointX == param->m_pPoin ts[param->m_PointCount - 4].m_PointX && 1919 if (param->m_PointCount >= 4 &&
1544 param->m_pPoints[param->m_PointCount - 3].m_PointY == param->m_pPoin ts[param->m_PointCount - 4].m_PointY && 1920 param->m_pPoints[param->m_PointCount - 4].m_Flag == FXPT_MOVETO &&
1545 param->m_pPoints[param->m_PointCount - 2].m_PointX == param->m_pPoin ts[param->m_PointCount - 4].m_PointX && 1921 param->m_pPoints[param->m_PointCount - 3].m_Flag == FXPT_BEZIERTO &&
1546 param->m_pPoints[param->m_PointCount - 2].m_PointY == param->m_pPoin ts[param->m_PointCount - 4].m_PointY && 1922 param->m_pPoints[param->m_PointCount - 3].m_PointX ==
1547 param->m_pPoints[param->m_PointCount - 1].m_PointX == param->m_pPoin ts[param->m_PointCount - 4].m_PointX && 1923 param->m_pPoints[param->m_PointCount - 4].m_PointX &&
1548 param->m_pPoints[param->m_PointCount - 1].m_PointY == param->m_pPoin ts[param->m_PointCount - 4].m_PointY) { 1924 param->m_pPoints[param->m_PointCount - 3].m_PointY ==
1549 param->m_PointCount -= 4; 1925 param->m_pPoints[param->m_PointCount - 4].m_PointY &&
1550 } 1926 param->m_pPoints[param->m_PointCount - 2].m_PointX ==
1927 param->m_pPoints[param->m_PointCount - 4].m_PointX &&
1928 param->m_pPoints[param->m_PointCount - 2].m_PointY ==
1929 param->m_pPoints[param->m_PointCount - 4].m_PointY &&
1930 param->m_pPoints[param->m_PointCount - 1].m_PointX ==
1931 param->m_pPoints[param->m_PointCount - 4].m_PointX &&
1932 param->m_pPoints[param->m_PointCount - 1].m_PointY ==
1933 param->m_pPoints[param->m_PointCount - 4].m_PointY) {
1934 param->m_PointCount -= 4;
1935 }
1551 } 1936 }
1552 extern "C" { 1937 extern "C" {
1553 static int _Outline_MoveTo(const FXFT_Vector* to, void* user) 1938 static int _Outline_MoveTo(const FXFT_Vector* to, void* user) {
1554 { 1939 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
1555 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; 1940 if (!param->m_bCount) {
1556 if (!param->m_bCount) { 1941 _Outline_CheckEmptyContour(param);
1557 _Outline_CheckEmptyContour(param); 1942 param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit;
1558 param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_Co ordUnit; 1943 param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit;
1559 param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_Co ordUnit; 1944 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_MOVETO;
1560 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_MOVETO; 1945 param->m_CurX = to->x;
1561 param->m_CurX = to->x; 1946 param->m_CurY = to->y;
1562 param->m_CurY = to->y; 1947 if (param->m_PointCount) {
1563 if (param->m_PointCount) { 1948 param->m_pPoints[param->m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE;
1564 param->m_pPoints[param->m_PointCount - 1].m_Flag |= FXPT_CLOSEFI GURE; 1949 }
1565 } 1950 }
1566 } 1951 param->m_PointCount++;
1567 param->m_PointCount ++; 1952 return 0;
1568 return 0; 1953 }
1569 }
1570 }; 1954 };
1571 extern "C" { 1955 extern "C" {
1572 static int _Outline_LineTo(const FXFT_Vector* to, void* user) 1956 static int _Outline_LineTo(const FXFT_Vector* to, void* user) {
1573 { 1957 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
1574 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; 1958 if (!param->m_bCount) {
1575 if (!param->m_bCount) { 1959 param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit;
1576 param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_Co ordUnit; 1960 param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit;
1577 param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_Co ordUnit; 1961 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_LINETO;
1578 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_LINETO; 1962 param->m_CurX = to->x;
1579 param->m_CurX = to->x; 1963 param->m_CurY = to->y;
1580 param->m_CurY = to->y; 1964 }
1581 } 1965 param->m_PointCount++;
1582 param->m_PointCount ++; 1966 return 0;
1583 return 0; 1967 }
1584 }
1585 }; 1968 };
1586 extern "C" { 1969 extern "C" {
1587 static int _Outline_ConicTo(const FXFT_Vector* control, const FXFT_Vector* t o, void* user) 1970 static int _Outline_ConicTo(const FXFT_Vector* control,
1588 { 1971 const FXFT_Vector* to,
1589 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; 1972 void* user) {
1590 if (!param->m_bCount) { 1973 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
1591 param->m_pPoints[param->m_PointCount].m_PointX = (param->m_CurX + (c ontrol->x - param->m_CurX) * 2 / 3) / param->m_CoordUnit; 1974 if (!param->m_bCount) {
1592 param->m_pPoints[param->m_PointCount].m_PointY = (param->m_CurY + (c ontrol->y - param->m_CurY) * 2 / 3) / param->m_CoordUnit; 1975 param->m_pPoints[param->m_PointCount].m_PointX =
1593 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO; 1976 (param->m_CurX + (control->x - param->m_CurX) * 2 / 3) /
1594 param->m_pPoints[param->m_PointCount + 1].m_PointX = (control->x + ( to->x - control->x) / 3) / param->m_CoordUnit; 1977 param->m_CoordUnit;
1595 param->m_pPoints[param->m_PointCount + 1].m_PointY = (control->y + ( to->y - control->y) / 3) / param->m_CoordUnit; 1978 param->m_pPoints[param->m_PointCount].m_PointY =
1596 param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO; 1979 (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) /
1597 param->m_pPoints[param->m_PointCount + 2].m_PointX = to->x / param-> m_CoordUnit; 1980 param->m_CoordUnit;
1598 param->m_pPoints[param->m_PointCount + 2].m_PointY = to->y / param-> m_CoordUnit; 1981 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO;
1599 param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO; 1982 param->m_pPoints[param->m_PointCount + 1].m_PointX =
1600 param->m_CurX = to->x; 1983 (control->x + (to->x - control->x) / 3) / param->m_CoordUnit;
1601 param->m_CurY = to->y; 1984 param->m_pPoints[param->m_PointCount + 1].m_PointY =
1602 } 1985 (control->y + (to->y - control->y) / 3) / param->m_CoordUnit;
1603 param->m_PointCount += 3; 1986 param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO;
1604 return 0; 1987 param->m_pPoints[param->m_PointCount + 2].m_PointX =
1605 } 1988 to->x / param->m_CoordUnit;
1989 param->m_pPoints[param->m_PointCount + 2].m_PointY =
1990 to->y / param->m_CoordUnit;
1991 param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO;
1992 param->m_CurX = to->x;
1993 param->m_CurY = to->y;
1994 }
1995 param->m_PointCount += 3;
1996 return 0;
1997 }
1606 }; 1998 };
1607 extern "C" { 1999 extern "C" {
1608 static int _Outline_CubicTo(const FXFT_Vector* control1, const FXFT_Vector* control2, const FXFT_Vector* to, void* user) 2000 static int _Outline_CubicTo(const FXFT_Vector* control1,
1609 { 2001 const FXFT_Vector* control2,
1610 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; 2002 const FXFT_Vector* to,
1611 if (!param->m_bCount) { 2003 void* user) {
1612 param->m_pPoints[param->m_PointCount].m_PointX = control1->x / param ->m_CoordUnit; 2004 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
1613 param->m_pPoints[param->m_PointCount].m_PointY = control1->y / param ->m_CoordUnit; 2005 if (!param->m_bCount) {
1614 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO; 2006 param->m_pPoints[param->m_PointCount].m_PointX =
1615 param->m_pPoints[param->m_PointCount + 1].m_PointX = control2->x / p aram->m_CoordUnit; 2007 control1->x / param->m_CoordUnit;
1616 param->m_pPoints[param->m_PointCount + 1].m_PointY = control2->y / p aram->m_CoordUnit; 2008 param->m_pPoints[param->m_PointCount].m_PointY =
1617 param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO; 2009 control1->y / param->m_CoordUnit;
1618 param->m_pPoints[param->m_PointCount + 2].m_PointX = to->x / param-> m_CoordUnit; 2010 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO;
1619 param->m_pPoints[param->m_PointCount + 2].m_PointY = to->y / param-> m_CoordUnit; 2011 param->m_pPoints[param->m_PointCount + 1].m_PointX =
1620 param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO; 2012 control2->x / param->m_CoordUnit;
1621 param->m_CurX = to->x; 2013 param->m_pPoints[param->m_PointCount + 1].m_PointY =
1622 param->m_CurY = to->y; 2014 control2->y / param->m_CoordUnit;
1623 } 2015 param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO;
1624 param->m_PointCount += 3; 2016 param->m_pPoints[param->m_PointCount + 2].m_PointX =
1625 return 0; 2017 to->x / param->m_CoordUnit;
1626 } 2018 param->m_pPoints[param->m_PointCount + 2].m_PointY =
2019 to->y / param->m_CoordUnit;
2020 param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO;
2021 param->m_CurX = to->x;
2022 param->m_CurY = to->y;
2023 }
2024 param->m_PointCount += 3;
2025 return 0;
2026 }
1627 }; 2027 };
1628 CFX_PathData* CFX_Font::LoadGlyphPath(FX_DWORD glyph_index, int dest_width) 2028 CFX_PathData* CFX_Font::LoadGlyphPath(FX_DWORD glyph_index, int dest_width) {
1629 { 2029 if (m_Face == NULL) {
1630 if (m_Face == NULL) { 2030 return NULL;
1631 return NULL; 2031 }
1632 } 2032 FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
1633 FXFT_Set_Pixel_Sizes(m_Face, 0, 64); 2033 FXFT_Matrix ft_matrix = { 65536, 0, 0, 65536 };
1634 FXFT_Matrix ft_matrix = {65536, 0, 0, 65536}; 2034 if (m_pSubstFont) {
1635 if (m_pSubstFont) { 2035 if (m_pSubstFont->m_ItalicAngle) {
1636 if (m_pSubstFont->m_ItalicAngle) { 2036 int skew = m_pSubstFont->m_ItalicAngle;
1637 int skew = m_pSubstFont->m_ItalicAngle; 2037 skew = skew <= -30 ? -58 : -g_AngleSkew[-skew];
1638 skew = skew <= -30 ? -58 : -g_AngleSkew[-skew]; 2038 if (m_bVertical) {
1639 if (m_bVertical) { 2039 ft_matrix.yx += ft_matrix.yy * skew / 100;
1640 ft_matrix.yx += ft_matrix.yy * skew / 100; 2040 } else {
1641 } else { 2041 ft_matrix.xy += -ft_matrix.xx * skew / 100;
1642 ft_matrix.xy += -ft_matrix.xx * skew / 100; 2042 }
1643 } 2043 }
1644 } 2044 if (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) {
1645 if (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) { 2045 AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight);
1646 AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight); 2046 }
1647 } 2047 }
1648 } 2048 int transflag = FXFT_Get_Face_Internal_Flag(m_Face);
1649 int transflag = FXFT_Get_Face_Internal_Flag(m_Face); 2049 FXFT_Set_Transform(m_Face, &ft_matrix, 0);
1650 FXFT_Set_Transform(m_Face, &ft_matrix, 0); 2050 int load_flags = (m_Face->face_flags & FT_FACE_FLAG_SFNT)
1651 int load_flags = (m_Face->face_flags & FT_FACE_FLAG_SFNT) ? FXFT_LOAD_NO_BIT MAP : FXFT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING; 2051 ? FXFT_LOAD_NO_BITMAP
1652 int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags); 2052 : FXFT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING;
1653 if (error) { 2053 int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags);
1654 FXFT_Set_Face_Internal_Flag(m_Face, transflag); 2054 if (error) {
1655 return NULL;
1656 }
1657 if (m_pSubstFont && !(m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && m_pSu bstFont->m_Weight > 400) {
1658 int level = 0;
1659 if (m_pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) {
1660 level = g_WeightPow_SHIFTJIS[(m_pSubstFont->m_Weight - 400) / 10] * 2 * 65536 / 36655;
1661 } else {
1662 level = g_WeightPow[(m_pSubstFont->m_Weight - 400) / 10] * 2;
1663 }
1664 FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level);
1665 }
1666 FXFT_Outline_Funcs funcs;
1667 funcs.move_to = _Outline_MoveTo;
1668 funcs.line_to = _Outline_LineTo;
1669 funcs.conic_to = _Outline_ConicTo;
1670 funcs.cubic_to = _Outline_CubicTo;
1671 funcs.shift = 0;
1672 funcs.delta = 0;
1673 OUTLINE_PARAMS params;
1674 params.m_bCount = TRUE;
1675 params.m_PointCount = 0;
1676 FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, &params);
1677 if (params.m_PointCount == 0) {
1678 FXFT_Set_Face_Internal_Flag(m_Face, transflag);
1679 return NULL;
1680 }
1681 CFX_PathData* pPath = FX_NEW CFX_PathData;
1682 if (!pPath) {
1683 return NULL;
1684 }
1685 pPath->SetPointCount(params.m_PointCount);
1686 params.m_bCount = FALSE;
1687 params.m_PointCount = 0;
1688 params.m_pPoints = pPath->GetPoints();
1689 params.m_CurX = params.m_CurY = 0;
1690 params.m_CoordUnit = 64 * 64.0;
1691 FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, &params);
1692 _Outline_CheckEmptyContour(&params);
1693 pPath->TrimPoints(params.m_PointCount);
1694 if (params.m_PointCount) {
1695 pPath->GetPoints()[params.m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE;
1696 }
1697 FXFT_Set_Face_Internal_Flag(m_Face, transflag); 2055 FXFT_Set_Face_Internal_Flag(m_Face, transflag);
1698 return pPath; 2056 return NULL;
1699 } 2057 }
1700 void _CFX_UniqueKeyGen::Generate(int count, ...) 2058 if (m_pSubstFont && !(m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) &&
1701 { 2059 m_pSubstFont->m_Weight > 400) {
1702 va_list argList; 2060 int level = 0;
1703 va_start(argList, count); 2061 if (m_pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) {
1704 for (int i = 0; i < count; i ++) { 2062 level = g_WeightPow_SHIFTJIS[(m_pSubstFont->m_Weight - 400) / 10] * 2 *
1705 int p = va_arg(argList, int); 2063 65536 / 36655;
1706 ((FX_DWORD*)m_Key)[i] = p; 2064 } else {
1707 } 2065 level = g_WeightPow[(m_pSubstFont->m_Weight - 400) / 10] * 2;
1708 va_end(argList); 2066 }
1709 m_KeyLen = count * sizeof(FX_DWORD); 2067 FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level);
1710 } 2068 }
2069 FXFT_Outline_Funcs funcs;
2070 funcs.move_to = _Outline_MoveTo;
2071 funcs.line_to = _Outline_LineTo;
2072 funcs.conic_to = _Outline_ConicTo;
2073 funcs.cubic_to = _Outline_CubicTo;
2074 funcs.shift = 0;
2075 funcs.delta = 0;
2076 OUTLINE_PARAMS params;
2077 params.m_bCount = TRUE;
2078 params.m_PointCount = 0;
2079 FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, &params);
2080 if (params.m_PointCount == 0) {
2081 FXFT_Set_Face_Internal_Flag(m_Face, transflag);
2082 return NULL;
2083 }
2084 CFX_PathData* pPath = FX_NEW CFX_PathData;
2085 if (!pPath) {
2086 return NULL;
2087 }
2088 pPath->SetPointCount(params.m_PointCount);
2089 params.m_bCount = FALSE;
2090 params.m_PointCount = 0;
2091 params.m_pPoints = pPath->GetPoints();
2092 params.m_CurX = params.m_CurY = 0;
2093 params.m_CoordUnit = 64 * 64.0;
2094 FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, &params);
2095 _Outline_CheckEmptyContour(&params);
2096 pPath->TrimPoints(params.m_PointCount);
2097 if (params.m_PointCount) {
2098 pPath->GetPoints()[params.m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE;
2099 }
2100 FXFT_Set_Face_Internal_Flag(m_Face, transflag);
2101 return pPath;
2102 }
2103 void _CFX_UniqueKeyGen::Generate(int count, ...) {
2104 va_list argList;
2105 va_start(argList, count);
2106 for (int i = 0; i < count; i++) {
2107 int p = va_arg(argList, int);
2108 ((FX_DWORD*)m_Key)[i] = p;
2109 }
2110 va_end(argList);
2111 m_KeyLen = count * sizeof(FX_DWORD);
2112 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698