OLD | NEW |
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, ¶ms); | 1950 FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, ¶ms); |
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, ¶ms); | 1961 FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, ¶ms); |
1701 _Outline_CheckEmptyContour(¶ms); | 1962 _Outline_CheckEmptyContour(¶ms); |
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 } | |
OLD | NEW |