7 FIXED
fixed_from_26dot6(signed long x
)
9 signed long y
= (x
<< 10);
10 return *(reinterpret_cast<FIXED
*>(&y
));
13 signed long fixed_to_26dot6(const FIXED
&x
)
15 return *(reinterpret_cast<const signed long *>(&x
)) >> 10;
18 signed long float_to_16dot16(double x
)
20 return static_cast<FT_Pos
>(x
* 65536);
23 LONG
int_from_16dot16(signed long x
)
25 const LONG ret
= (x
>> 16);
27 if (ret
== 0 && x
> 0)
33 LONG
int_from_26dot6(signed long x
)
35 const LONG ret
= (x
>> 6);
37 if (ret
== 0 && x
> 0)
43 DWORD
create_tls_index()
45 DWORD new_tls_index
= TlsAlloc();
46 assert(new_tls_index
!= TLS_OUT_OF_INDEXES
);
51 BOOL
free_tls_index(DWORD tls_index
)
53 return TlsFree(tls_index
);
56 BYTE
division_by_255(short number
, short numerator
)
58 // there are many approaches to approximate number * numerator / 255
59 // it is a trade-off between efficiency and accuracy
61 const int t
= number
* numerator
;
62 return (((t
+ 255) >> 8) + t
) >> 8;
65 uint128_t
generate_render_trait(const LOGFONTW
*logfont
, int render_mode
)
67 // the LOGFONTW structure and render mode are the minimal set that uniquely determine font metrics used by any renderer
69 // exclude the bytes after the face name, which may contain junk data
70 const int lf_metric_size
= sizeof(LOGFONTW
) - sizeof(logfont
->lfFaceName
);
71 const int lf_facename_size
= static_cast<const int>((wcslen(logfont
->lfFaceName
) * sizeof(wchar_t)));
72 const int lf_total_size
= lf_metric_size
+ lf_facename_size
;
74 uint128_t render_trait
;
76 MurmurHash3_x64_128(logfont
, lf_total_size
, render_mode
, &render_trait
);
78 MurmurHash3_x86_128(logfont
, lf_total_size
, render_mode
, &render_trait
);
83 POINT
get_baseline(UINT alignment
, int x
, int y
, int width
, int ascent
, int descent
)
85 POINT baseline
= {x
, y
};
87 switch ((TA_LEFT
| TA_RIGHT
| TA_CENTER
) & alignment
)
95 baseline
.x
-= width
/ 2;
99 switch ((TA_TOP
| TA_BOTTOM
| TA_BASELINE
) & alignment
)
102 baseline
.y
+= ascent
;
105 baseline
.y
-= descent
;
114 int get_bmp_pitch(int width
, WORD bpp
)
116 #define FT_PAD_FLOOR( x, n ) ( (x) & ~((n)-1) )
117 #define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n )
118 #define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + ((n)-1), n )
120 return FT_PAD_CEIL(static_cast<int>(ceil(static_cast<double>(width
* bpp
) / 8)), sizeof(LONG
));
123 bool get_dc_bmp_header(HDC hdc
, BITMAPINFOHEADER
&dc_bmp_header
)
125 dc_bmp_header
.biSize
= sizeof(BITMAPINFOHEADER
);
127 const HBITMAP dc_bitmap
= static_cast<const HBITMAP
>(GetCurrentObject(hdc
, OBJ_BITMAP
));
128 if (dc_bitmap
== NULL
)
130 // currently no selected bitmap
133 dc_bmp_header
.biWidth
= GetDeviceCaps(hdc
, HORZRES
);
134 dc_bmp_header
.biHeight
= GetDeviceCaps(hdc
, VERTRES
);
135 dc_bmp_header
.biPlanes
= GetDeviceCaps(hdc
, PLANES
);
136 dc_bmp_header
.biBitCount
= GetDeviceCaps(hdc
, BITSPIXEL
);
142 // do not return the color table
143 dc_bmp_header
.biBitCount
= 0;
144 const int i_ret
= GetDIBits(hdc
, dc_bitmap
, 0, 0, NULL
, reinterpret_cast<LPBITMAPINFO
>(&dc_bmp_header
), DIB_RGB_COLORS
);
151 OUTLINETEXTMETRICW
*get_dc_metrics(HDC hdc
, std::vector
<BYTE
> &metric_buf
)
153 // get outline metrics of the DC, which also include the text metrics
155 UINT metric_size
= GetOutlineTextMetricsW(hdc
, 0, NULL
);
156 if (metric_size
== 0)
159 metric_buf
.resize(metric_size
);
160 OUTLINETEXTMETRICW
*outline_metrics
= reinterpret_cast<OUTLINETEXTMETRICW
*>(&metric_buf
[0]);
161 metric_size
= GetOutlineTextMetricsW(hdc
, metric_size
, outline_metrics
);
162 assert(metric_size
!= 0);
164 return outline_metrics
;
167 int get_glyph_bmp_width(const FT_Bitmap
&bitmap
)
169 if (bitmap
.pixel_mode
== FT_PIXEL_MODE_LCD
)
170 return bitmap
.width
/ 3;
175 /*LONG get_glyph_run_width(const glyph_run *a_glyph_run, bool is_control_width)
177 assert(a_glyph_run != NULL);
179 std::list<RECT>::const_iterator first_box_iter;
180 std::list<RECT>::const_reverse_iterator last_box_iter;
182 if (is_control_width)
184 // use control box metrics
185 first_box_iter = a_glyph_run->ctrl_boxes.begin();
186 last_box_iter = a_glyph_run->ctrl_boxes.rbegin();
190 // use black box metrics
191 first_box_iter = a_glyph_run->black_boxes.begin();
192 last_box_iter = a_glyph_run->black_boxes.rbegin();
195 if (a_glyph_run->ctrl_boxes.back().left >= a_glyph_run->ctrl_boxes.front().left)
196 return last_box_iter->right - first_box_iter->left;
198 return first_box_iter->right - last_box_iter->left;
201 LOGFONTW
get_log_font(HDC hdc
)
203 HFONT h_font
= reinterpret_cast<HFONT
>(GetCurrentObject(hdc
, OBJ_FONT
));
204 assert(h_font
!= NULL
);
207 GetObject(h_font
, sizeof(LOGFONTW
), &font_attr
);
212 bool get_render_mode(const render_config_static::render_mode_static
&render_mode_conf
, WORD dc_bmp_bpp
, BYTE font_quality
, FT_Render_Mode
*render_mode
)
214 // return true if successfully find an appropriate render mode
215 // otherwise return false
217 if (render_mode_conf
.mono
== 2)
219 *render_mode
= FT_RENDER_MODE_MONO
;
223 if (render_mode_conf
.gray
== 2)
225 *render_mode
= FT_RENDER_MODE_NORMAL
;
229 if (render_mode_conf
.subpixel
== 2)
231 *render_mode
= FT_RENDER_MODE_LCD
;
235 if (!render_mode_conf
.aliased
&& font_quality
== NONANTIALIASED_QUALITY
)
238 if (render_mode_conf
.mono
== 1 && dc_bmp_bpp
== 1)
240 *render_mode
= FT_RENDER_MODE_MONO
;
244 if (render_mode_conf
.gray
== 1 && dc_bmp_bpp
== 8)
246 *render_mode
= FT_RENDER_MODE_NORMAL
;
250 // we do not support 16 bpp currently
252 if (render_mode_conf
.subpixel
== 1 && dc_bmp_bpp
>= 24)
254 *render_mode
= FT_RENDER_MODE_LCD
;
261 bool operator<(const LOGFONTW
&lf1
, const LOGFONTW
&lf2
)
263 return memcmp(&lf1
, &lf2
, sizeof(LOGFONTW
)) < 0;
266 bool mb_to_wc(const char *multi_byte_str
, int count
, std::wstring
&wide_char_str
)
268 int wc_str_len
= MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, multi_byte_str
, count
, NULL
, 0);
272 wide_char_str
.resize(wc_str_len
);
273 wc_str_len
= MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, multi_byte_str
, count
, &wide_char_str
[0], wc_str_len
);
280 BOOL
paint_background(HDC hdc
, const RECT
*bg_rect
, COLORREF bg_color
)
284 if (bg_color
== CLR_INVALID
)
287 const HBRUSH bg_brush
= CreateSolidBrush(bg_color
);
288 if (bg_brush
== NULL
)
291 i_ret
= FillRect(hdc
, bg_rect
, bg_brush
);
295 DeleteObject(bg_brush
);