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

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

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

Powered by Google App Engine
This is Rietveld 408576698