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