w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

cairo-win32-font.c
Go to the documentation of this file.
1 /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2 /* cairo - a vector graphics library with display and print output
3  *
4  * Copyright © 2005 Red Hat, Inc
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it either under the terms of the GNU Lesser General Public
8  * License version 2.1 as published by the Free Software Foundation
9  * (the "LGPL") or, at your option, under the terms of the Mozilla
10  * Public License Version 1.1 (the "MPL"). If you do not alter this
11  * notice, a recipient may use your version of this file under either
12  * the MPL or the LGPL.
13  *
14  * You should have received a copy of the LGPL along with this library
15  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17  * You should have received a copy of the MPL along with this library
18  * in the file COPYING-MPL-1.1
19  *
20  * The contents of this file are subject to the Mozilla Public License
21  * Version 1.1 (the "License"); you may not use this file except in
22  * compliance with the License. You may obtain a copy of the License at
23  * http://www.mozilla.org/MPL/
24  *
25  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27  * the specific language governing rights and limitations.
28  *
29  * The Original Code is the cairo graphics library.
30  *
31  * The Initial Developer of the Original Code is Red Hat, Inc.
32  *
33  * Contributor(s):
34  */
35 
36 #define WIN32_LEAN_AND_MEAN
37 /* We require Windows 2000 features such as GetGlyphIndices */
38 #if !defined(WINVER) || (WINVER < 0x0500)
39 # define WINVER 0x0500
40 #endif
41 #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
42 # define _WIN32_WINNT 0x0500
43 #endif
44 
45 #include "cairoint.h"
46 
47 #include "cairo-win32-private.h"
48 
49 #include "cairo-array-private.h"
50 #include "cairo-error-private.h"
52 #include "cairo-pattern-private.h"
54 
55 #include <wchar.h>
56 
57 #ifndef SPI_GETFONTSMOOTHINGTYPE
58 #define SPI_GETFONTSMOOTHINGTYPE 0x200a
59 #endif
60 #ifndef FE_FONTSMOOTHINGCLEARTYPE
61 #define FE_FONTSMOOTHINGCLEARTYPE 2
62 #endif
63 #ifndef CLEARTYPE_QUALITY
64 #define CLEARTYPE_QUALITY 5
65 #endif
66 #ifndef TT_PRIM_CSPLINE
67 #define TT_PRIM_CSPLINE 3
68 #endif
69 
70 #define CMAP_TAG 0x70616d63
71 
72 /**
73  * SECTION:cairo-win32-fonts
74  * @Title: Win32 Fonts
75  * @Short_Description: Font support for Microsoft Windows
76  * @See_Also: #cairo_font_face_t
77  *
78  * The Microsoft Windows font backend is primarily used to render text on
79  * Microsoft Windows systems.
80  **/
81 
82 /**
83  * CAIRO_HAS_WIN32_FONT:
84  *
85  * Defined if the Microsoft Windows font backend is available.
86  * This macro can be used to conditionally compile backend-specific code.
87  *
88  * Since: 1.8
89  **/
90 
92 
93 typedef struct {
95 
96  LOGFONTW logfont;
97 
98  BYTE quality;
99 
100  /* We do drawing and metrics computation in a "logical space" which
101  * is similar to font space, except that it is scaled by a factor
102  * of the (desired font size) * (WIN32_FONT_LOGICAL_SCALE). The multiplication
103  * by WIN32_FONT_LOGICAL_SCALE allows for sub-pixel precision.
104  */
105  double logical_scale;
106 
107  /* The size we should actually request the font at from Windows; differs
108  * from the logical_scale because it is quantized for orthogonal
109  * transformations
110  */
111  double logical_size;
112 
113  /* Transformations from device <=> logical space
114  */
115  cairo_matrix_t logical_to_device;
116  cairo_matrix_t device_to_logical;
117 
118  /* We special case combinations of 90-degree-rotations, scales and
119  * flips ... that is transformations that take the axes to the
120  * axes. If preserve_axes is true, then swap_axes/swap_x/swap_y
121  * encode the 8 possibilities for orientation (4 rotation angles with
122  * and without a flip), and scale_x, scale_y the scale components.
123  */
124  cairo_bool_t preserve_axes;
125  cairo_bool_t swap_axes;
126  cairo_bool_t swap_x;
127  cairo_bool_t swap_y;
128  double x_scale;
129  double y_scale;
130 
131  /* The size of the design unit of the font
132  */
133  int em_square;
134 
135  HFONT scaled_hfont;
136  HFONT unscaled_hfont;
137 
138  cairo_bool_t is_bitmap;
140  cairo_bool_t delete_scaled_hfont;
141  cairo_bool_t has_type1_notdef_index;
142  unsigned long type1_notdef_index;
144 
145 static cairo_status_t
147 
148 static cairo_status_t
150  cairo_scaled_glyph_t *scaled_glyph);
151 
152 static cairo_status_t
154  cairo_scaled_glyph_t *scaled_glyph);
155 
156 static cairo_status_t
158  cairo_scaled_glyph_t *scaled_glyph);
159 
160 #define NEARLY_ZERO(d) (fabs(d) < (1. / 65536.))
161 
162 static HDC
164 {
165  static HDC hdc;
166 
167  if (!hdc) {
168  hdc = CreateCompatibleDC (NULL);
169  if (!hdc) {
170  _cairo_win32_print_gdi_error ("_get_global_font_dc");
171  return NULL;
172  }
173 
174  if (!SetGraphicsMode (hdc, GM_ADVANCED)) {
175  _cairo_win32_print_gdi_error ("_get_global_font_dc");
176  DeleteDC (hdc);
177  return NULL;
178  }
179  }
180 
181  return hdc;
182 }
183 
184 static cairo_status_t
187 {
189 
190  if (NEARLY_ZERO (sc->yx) && NEARLY_ZERO (sc->xy) &&
191  !NEARLY_ZERO(sc->xx) && !NEARLY_ZERO(sc->yy)) {
192  scaled_font->preserve_axes = TRUE;
193  scaled_font->x_scale = sc->xx;
194  scaled_font->swap_x = (sc->xx < 0);
195  scaled_font->y_scale = sc->yy;
196  scaled_font->swap_y = (sc->yy < 0);
197  scaled_font->swap_axes = FALSE;
198 
199  } else if (NEARLY_ZERO (sc->xx) && NEARLY_ZERO (sc->yy) &&
200  !NEARLY_ZERO(sc->yx) && !NEARLY_ZERO(sc->xy)) {
201  scaled_font->preserve_axes = TRUE;
202  scaled_font->x_scale = sc->yx;
203  scaled_font->swap_x = (sc->yx < 0);
204  scaled_font->y_scale = sc->xy;
205  scaled_font->swap_y = (sc->xy < 0);
206  scaled_font->swap_axes = TRUE;
207 
208  } else {
209  scaled_font->preserve_axes = FALSE;
210  scaled_font->swap_x = scaled_font->swap_y = scaled_font->swap_axes = FALSE;
211  }
212 
213  if (scaled_font->preserve_axes) {
214  if (scaled_font->swap_x)
215  scaled_font->x_scale = - scaled_font->x_scale;
216  if (scaled_font->swap_y)
217  scaled_font->y_scale = - scaled_font->y_scale;
218 
219  scaled_font->logical_scale = WIN32_FONT_LOGICAL_SCALE * scaled_font->y_scale;
220  scaled_font->logical_size = WIN32_FONT_LOGICAL_SCALE *
221  _cairo_lround (scaled_font->y_scale);
222  }
223 
224  /* The font matrix has x and y "scale" components which we extract and
225  * use as character scale values.
226  */
227  cairo_matrix_init (&scaled_font->logical_to_device,
228  sc->xx, sc->yx, sc->xy, sc->yy, 0, 0);
229 
230  if (!scaled_font->preserve_axes) {
232  &scaled_font->x_scale, &scaled_font->y_scale,
233  TRUE); /* XXX: Handle vertical text */
234  if (status)
235  return status;
236 
237  scaled_font->logical_size =
239  scaled_font->logical_scale =
240  WIN32_FONT_LOGICAL_SCALE * scaled_font->y_scale;
241  }
242 
243  cairo_matrix_scale (&scaled_font->logical_to_device,
244  1.0 / scaled_font->logical_scale,
245  1.0 / scaled_font->logical_scale);
246 
247  scaled_font->device_to_logical = scaled_font->logical_to_device;
248 
249  status = cairo_matrix_invert (&scaled_font->device_to_logical);
250  if (status)
252 
253  return CAIRO_STATUS_SUCCESS;
254 }
255 
256 static cairo_bool_t
258 {
259  OSVERSIONINFO version_info;
260 
261  version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
262 
263  if (!GetVersionEx (&version_info)) {
264  _cairo_win32_print_gdi_error ("_have_cleartype_quality");
265  return FALSE;
266  }
267 
268  return (version_info.dwMajorVersion > 5 ||
269  (version_info.dwMajorVersion == 5 &&
270  version_info.dwMinorVersion >= 1)); /* XP or newer */
271 }
272 
273 static BYTE
275 {
276  BOOL font_smoothing;
277  UINT smoothing_type;
278 
279  if (!SystemParametersInfo (SPI_GETFONTSMOOTHING, 0, &font_smoothing, 0)) {
280  _cairo_win32_print_gdi_error ("_get_system_quality");
281  return DEFAULT_QUALITY;
282  }
283 
284  if (font_smoothing) {
285  if (_have_cleartype_quality ()) {
286  if (!SystemParametersInfo (SPI_GETFONTSMOOTHINGTYPE,
287  0, &smoothing_type, 0)) {
288  _cairo_win32_print_gdi_error ("_get_system_quality");
289  return DEFAULT_QUALITY;
290  }
291 
292  if (smoothing_type == FE_FONTSMOOTHINGCLEARTYPE)
293  return CLEARTYPE_QUALITY;
294  }
295 
296  return ANTIALIASED_QUALITY;
297  } else {
298  return DEFAULT_QUALITY;
299  }
300 }
301 
302 /* If face_hfont is non-%NULL then font_matrix must be a simple scale by some
303  * factor S, ctm must be the identity, logfont->lfHeight must be -S,
304  * logfont->lfWidth, logfont->lfEscapement, logfont->lfOrientation must
305  * all be 0, and face_hfont is the result of calling CreateFontIndirectW on
306  * logfont.
307  */
308 static cairo_status_t
309 _win32_scaled_font_create (LOGFONTW *logfont,
310  HFONT face_hfont,
312  const cairo_matrix_t *font_matrix,
313  const cairo_matrix_t *ctm,
315  cairo_scaled_font_t **font_out)
316 {
317  HDC hdc;
321 
323  if (hdc == NULL)
325 
327  if (f == NULL)
329 
330  f->logfont = *logfont;
331 
332  /* We don't have any control over the hinting style or subpixel
333  * order in the Win32 font API, so we ignore those parts of
334  * cairo_font_options_t. We use the 'antialias' field to set
335  * the 'quality'.
336  *
337  * XXX: The other option we could pay attention to, but don't
338  * here is the hint_metrics options.
339  */
340  if (options->antialias == CAIRO_ANTIALIAS_DEFAULT)
341  f->quality = _get_system_quality ();
342  else {
343  switch (options->antialias) {
345  f->quality = NONANTIALIASED_QUALITY;
346  break;
350  f->quality = ANTIALIASED_QUALITY;
351  break;
355  f->quality = CLEARTYPE_QUALITY;
356  else
357  f->quality = ANTIALIASED_QUALITY;
358  break;
361  }
362  }
363 
364  f->em_square = 0;
365  f->scaled_hfont = NULL;
366  f->unscaled_hfont = NULL;
367  f->has_type1_notdef_index = FALSE;
368 
369  if (f->quality == logfont->lfQuality ||
370  (logfont->lfQuality == DEFAULT_QUALITY &&
371  options->antialias == CAIRO_ANTIALIAS_DEFAULT)) {
372  /* If face_hfont is non-NULL, then we can use it to avoid creating our
373  * own --- because the constraints on face_hfont mentioned above
374  * guarantee it was created in exactly the same way that
375  * _win32_scaled_font_get_scaled_hfont would create it.
376  */
377  f->scaled_hfont = face_hfont;
378  }
379  /* don't delete the hfont if we're using the one passed in to us */
380  f->delete_scaled_hfont = !f->scaled_hfont;
381 
382  cairo_matrix_multiply (&scale, font_matrix, ctm);
384  if (status)
385  goto FAIL;
386 
388  font_matrix, ctm, options,
390  if (status)
391  goto FAIL;
392 
394  if (status) {
395  _cairo_scaled_font_fini (&f->base);
396  goto FAIL;
397  }
398 
399  *font_out = &f->base;
400  return CAIRO_STATUS_SUCCESS;
401 
402  FAIL:
403  free (f);
404  return status;
405 }
406 
407 static cairo_status_t
409  HDC hdc)
410 {
411  XFORM xform;
412 
413  _cairo_matrix_to_win32_xform (&scaled_font->logical_to_device, &xform);
414 
415  if (!SetWorldTransform (hdc, &xform))
416  return _cairo_win32_print_gdi_error ("_win32_scaled_font_set_world_transform");
417 
418  return CAIRO_STATUS_SUCCESS;
419 }
420 
421 static cairo_status_t
423 {
424  if (!ModifyWorldTransform (hdc, NULL, MWT_IDENTITY))
425  return _cairo_win32_print_gdi_error ("_win32_scaled_font_set_identity_transform");
426 
427  return CAIRO_STATUS_SUCCESS;
428 }
429 
430 static cairo_status_t
432  HFONT *hfont_out)
433 {
434  if (!scaled_font->scaled_hfont) {
435  LOGFONTW logfont = scaled_font->logfont;
436  logfont.lfHeight = -scaled_font->logical_size;
437  logfont.lfWidth = 0;
438  logfont.lfEscapement = 0;
439  logfont.lfOrientation = 0;
440  logfont.lfQuality = scaled_font->quality;
441 
442  scaled_font->scaled_hfont = CreateFontIndirectW (&logfont);
443  if (!scaled_font->scaled_hfont)
444  return _cairo_win32_print_gdi_error ("_win32_scaled_font_get_scaled_hfont");
445  }
446 
447  *hfont_out = scaled_font->scaled_hfont;
448  return CAIRO_STATUS_SUCCESS;
449 }
450 
451 static cairo_status_t
453  HDC hdc,
454  HFONT *hfont_out)
455 {
456  if (scaled_font->unscaled_hfont == NULL) {
457  OUTLINETEXTMETRIC *otm;
458  unsigned int otm_size;
459  HFONT scaled_hfont;
460  LOGFONTW logfont;
462 
464  &scaled_hfont);
465  if (status)
466  return status;
467 
468  if (! SelectObject (hdc, scaled_hfont))
469  return _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:SelectObject");
470 
471  otm_size = GetOutlineTextMetrics (hdc, 0, NULL);
472  if (! otm_size)
473  return _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:GetOutlineTextMetrics");
474 
475  otm = _cairo_malloc (otm_size);
476  if (otm == NULL)
478 
479  if (! GetOutlineTextMetrics (hdc, otm_size, otm)) {
480  status = _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:GetOutlineTextMetrics");
481  free (otm);
482  return status;
483  }
484 
485  scaled_font->em_square = otm->otmEMSquare;
486  free (otm);
487 
488  logfont = scaled_font->logfont;
489  logfont.lfHeight = -scaled_font->em_square;
490  logfont.lfWidth = 0;
491  logfont.lfEscapement = 0;
492  logfont.lfOrientation = 0;
493  logfont.lfQuality = scaled_font->quality;
494 
495  scaled_font->unscaled_hfont = CreateFontIndirectW (&logfont);
496  if (! scaled_font->unscaled_hfont)
497  return _cairo_win32_print_gdi_error ("_win32_scaled_font_get_unscaled_hfont:CreateIndirect");
498  }
499 
500  *hfont_out = scaled_font->unscaled_hfont;
501  return CAIRO_STATUS_SUCCESS;
502 }
503 
504 static cairo_status_t
506  HDC hdc)
507 {
509  HFONT hfont;
510  HFONT old_hfont = NULL;
511 
513  if (status)
514  return status;
515 
516  old_hfont = SelectObject (hdc, hfont);
517  if (!old_hfont)
518  return _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_select_unscaled_font");
519 
521  if (status) {
522  SelectObject (hdc, old_hfont);
523  return status;
524  }
525 
526  SetMapMode (hdc, MM_TEXT);
527 
528  return CAIRO_STATUS_SUCCESS;
529 }
530 
533 {
534  cairo_win32_scaled_font_t *win32_scaled_font;
535 
536  win32_scaled_font = (cairo_win32_scaled_font_t *) scaled_font;
537 
538  return win32_scaled_font->is_type1;
539 }
540 
543 {
544  cairo_win32_scaled_font_t *win32_scaled_font;
545 
546  win32_scaled_font = (cairo_win32_scaled_font_t *) scaled_font;
547 
548  return win32_scaled_font->is_bitmap;
549 }
550 
551 static void
553 {
554 }
555 
556 /* implement the font backend interface */
557 
558 static cairo_status_t
561 {
562  LOGFONTW logfont;
563  uint16_t *face_name;
564  int face_name_len;
566 
567  status = _cairo_utf8_to_utf16 (toy_face->family, -1,
568  &face_name, &face_name_len);
569  if (status)
570  return status;
571 
572  if (face_name_len > LF_FACESIZE - 1)
573  face_name_len = LF_FACESIZE - 1;
574 
575  memcpy (logfont.lfFaceName, face_name, sizeof (uint16_t) * face_name_len);
576  logfont.lfFaceName[face_name_len] = 0;
577  free (face_name);
578 
579  logfont.lfHeight = 0; /* filled in later */
580  logfont.lfWidth = 0; /* filled in later */
581  logfont.lfEscapement = 0; /* filled in later */
582  logfont.lfOrientation = 0; /* filled in later */
583 
584  switch (toy_face->weight) {
586  default:
587  logfont.lfWeight = FW_NORMAL;
588  break;
590  logfont.lfWeight = FW_BOLD;
591  break;
592  }
593 
594  switch (toy_face->slant) {
596  default:
597  logfont.lfItalic = FALSE;
598  break;
601  logfont.lfItalic = TRUE;
602  break;
603  }
604 
605  logfont.lfUnderline = FALSE;
606  logfont.lfStrikeOut = FALSE;
607  /* The docs for LOGFONT discourage using this, since the
608  * interpretation is locale-specific, but it's not clear what
609  * would be a better alternative.
610  */
611  logfont.lfCharSet = DEFAULT_CHARSET;
612  logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
613  logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
614  logfont.lfQuality = DEFAULT_QUALITY; /* filled in later */
615  logfont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
616 
618 
619  return CAIRO_STATUS_SUCCESS;
620 }
621 
622 static void
623 _cairo_win32_scaled_font_fini (void *abstract_font)
624 {
625  cairo_win32_scaled_font_t *scaled_font = abstract_font;
626 
627  if (scaled_font == NULL)
628  return;
629 
630  if (scaled_font->scaled_hfont && scaled_font->delete_scaled_hfont)
631  DeleteObject (scaled_font->scaled_hfont);
632 
633  if (scaled_font->unscaled_hfont)
634  DeleteObject (scaled_font->unscaled_hfont);
635 }
636 
637 static cairo_int_status_t
639  double x,
640  double y,
641  const char *utf8,
643  int *num_glyphs)
644 {
645  uint16_t *utf16;
646  int n16;
647  int i;
648  WORD *glyph_indices = NULL;
650  double x_pos, y_pos;
651  HDC hdc = NULL;
652  cairo_matrix_t mat;
653 
654  status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &n16);
655  if (status)
656  return status;
657 
658  glyph_indices = _cairo_malloc_ab (n16 + 1, sizeof (WORD));
659  if (!glyph_indices) {
661  goto FAIL1;
662  }
663 
665  assert (hdc != NULL);
666 
668  if (status)
669  goto FAIL2;
670 
671  if (GetGlyphIndicesW (hdc, utf16, n16, glyph_indices, 0) == GDI_ERROR) {
672  status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_type1_text_to_glyphs:GetGlyphIndicesW");
673  goto FAIL3;
674  }
675 
676  *num_glyphs = n16;
677  *glyphs = _cairo_malloc_ab (n16, sizeof (cairo_glyph_t));
678  if (!*glyphs) {
680  goto FAIL3;
681  }
682 
683  x_pos = x;
684  y_pos = y;
685 
686  mat = scaled_font->base.ctm;
687  status = cairo_matrix_invert (&mat);
689 
690  _cairo_scaled_font_freeze_cache (&scaled_font->base);
691 
692  for (i = 0; i < n16; i++) {
693  cairo_scaled_glyph_t *scaled_glyph;
694 
695  (*glyphs)[i].index = glyph_indices[i];
696  (*glyphs)[i].x = x_pos;
697  (*glyphs)[i].y = y_pos;
698 
699  status = _cairo_scaled_glyph_lookup (&scaled_font->base,
700  glyph_indices[i],
702  &scaled_glyph);
703  if (status) {
704  free (*glyphs);
705  *glyphs = NULL;
706  break;
707  }
708 
709  x = scaled_glyph->x_advance;
710  y = scaled_glyph->y_advance;
712  x_pos += x;
713  y_pos += y;
714  }
715 
716  _cairo_scaled_font_thaw_cache (&scaled_font->base);
717 
718 FAIL3:
719  cairo_win32_scaled_font_done_font (&scaled_font->base);
720 FAIL2:
721  free (glyph_indices);
722 FAIL1:
723  free (utf16);
724 
725  return status;
726 }
727 
728 static cairo_int_status_t
730  double x,
731  double y,
732  const char *utf8,
734  int *num_glyphs)
735 {
736  cairo_win32_scaled_font_t *scaled_font = abstract_font;
737  uint16_t *utf16;
738  int n16;
739  GCP_RESULTSW gcp_results;
740  unsigned int buffer_size, i;
741  WCHAR *glyph_indices = NULL;
742  int *dx = NULL;
744  double x_pos, y_pos;
745  double x_incr, y_incr;
746  HDC hdc = NULL;
747 
748  /* GetCharacterPlacement() returns utf16 instead of glyph indices
749  * for Type 1 fonts. Use GetGlyphIndices for Type 1 fonts. */
750  if (scaled_font->is_type1)
752  x,
753  y,
754  utf8,
755  glyphs,
756  num_glyphs);
757 
758  /* Compute a vector in user space along the baseline of length one logical space unit */
759  x_incr = 1;
760  y_incr = 0;
761  cairo_matrix_transform_distance (&scaled_font->base.font_matrix, &x_incr, &y_incr);
762  x_incr /= scaled_font->logical_scale;
763  y_incr /= scaled_font->logical_scale;
764 
765  status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &n16);
766  if (status)
767  return status;
768 
769  gcp_results.lStructSize = sizeof (GCP_RESULTS);
770  gcp_results.lpOutString = NULL;
771  gcp_results.lpOrder = NULL;
772  gcp_results.lpCaretPos = NULL;
773  gcp_results.lpClass = NULL;
774 
775  buffer_size = MAX (n16 * 1.2, 16); /* Initially guess number of chars plus a few */
776  if (buffer_size > INT_MAX) {
778  goto FAIL1;
779  }
780 
782  assert (hdc != NULL);
783 
785  if (status)
786  goto FAIL1;
787 
788  while (TRUE) {
789  free (glyph_indices);
790  glyph_indices = NULL;
791 
792  free (dx);
793  dx = NULL;
794 
795  glyph_indices = _cairo_malloc_ab (buffer_size, sizeof (WCHAR));
796  dx = _cairo_malloc_ab (buffer_size, sizeof (int));
797  if (!glyph_indices || !dx) {
799  goto FAIL2;
800  }
801 
802  gcp_results.nGlyphs = buffer_size;
803  gcp_results.lpDx = dx;
804  gcp_results.lpGlyphs = glyph_indices;
805 
806  if (!GetCharacterPlacementW (hdc, utf16, n16,
807  0,
808  &gcp_results,
809  GCP_DIACRITIC | GCP_LIGATE | GCP_GLYPHSHAPE | GCP_REORDER)) {
810  status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_text_to_glyphs");
811  goto FAIL2;
812  }
813 
814  if (gcp_results.lpDx && gcp_results.lpGlyphs)
815  break;
816 
817  /* Too small a buffer, try again */
818 
819  buffer_size += buffer_size / 2;
820  if (buffer_size > INT_MAX) {
822  goto FAIL2;
823  }
824  }
825 
826  *num_glyphs = gcp_results.nGlyphs;
827  *glyphs = _cairo_malloc_ab (gcp_results.nGlyphs, sizeof (cairo_glyph_t));
828  if (!*glyphs) {
830  goto FAIL2;
831  }
832 
833  x_pos = x;
834  y_pos = y;
835 
836  for (i = 0; i < gcp_results.nGlyphs; i++) {
837  (*glyphs)[i].index = glyph_indices[i];
838  (*glyphs)[i].x = x_pos ;
839  (*glyphs)[i].y = y_pos;
840 
841  x_pos += x_incr * dx[i];
842  y_pos += y_incr * dx[i];
843  }
844 
845  FAIL2:
846  free (glyph_indices);
847  free (dx);
848 
849  cairo_win32_scaled_font_done_font (&scaled_font->base);
850 
851  FAIL1:
852  free (utf16);
853 
854  return status;
855 }
856 
857 static unsigned long
859  uint32_t ucs4)
860 {
861  cairo_win32_scaled_font_t *scaled_font = abstract_font;
862  wchar_t unicode[2];
864  HDC hdc = NULL;
866 
868  assert (hdc != NULL);
869 
871  if (status)
872  return 0;
873 
874  unicode[0] = ucs4;
875  unicode[1] = 0;
876  if (GetGlyphIndicesW (hdc, unicode, 1, &glyph_index, 0) == GDI_ERROR) {
877  _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_ucs4_to_index:GetGlyphIndicesW");
878  glyph_index = 0;
879  }
880 
881  cairo_win32_scaled_font_done_font (&scaled_font->base);
882 
883  return glyph_index;
884 }
885 
886 static cairo_status_t
888 {
891 
892  TEXTMETRIC metrics = {0};
893  HDC hdc;
894 
896  assert (hdc != NULL);
897 
898  if (scaled_font->preserve_axes || scaled_font->base.options.hint_metrics == CAIRO_HINT_METRICS_OFF) {
899  /* For 90-degree rotations (including 0), we get the metrics
900  * from the GDI in logical space, then convert back to font space
901  */
903  if (status)
904  return status;
905 
906  if (!GetTextMetrics (hdc, &metrics)) {
907  status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_set_metrics:GetTextMetrics");
908  }
909 
910  cairo_win32_scaled_font_done_font (&scaled_font->base);
911  if (status)
912  return status;
913 
914  extents.ascent = metrics.tmAscent / scaled_font->logical_scale;
915  extents.descent = metrics.tmDescent / scaled_font->logical_scale;
916 
917  extents.height = (metrics.tmHeight + metrics.tmExternalLeading) / scaled_font->logical_scale;
918  extents.max_x_advance = metrics.tmMaxCharWidth / scaled_font->logical_scale;
919  extents.max_y_advance = 0;
920 
921  } else {
922  /* For all other transformations, we use the design metrics
923  * of the font. The GDI results from GetTextMetrics() on a
924  * transformed font are inexplicably large and we want to
925  * avoid them.
926  */
928  if (status)
929  return status;
930  GetTextMetrics (hdc, &metrics);
932 
933  extents.ascent = (double)metrics.tmAscent / scaled_font->em_square;
934  extents.descent = (double)metrics.tmDescent / scaled_font->em_square;
935  extents.height = (double)(metrics.tmHeight + metrics.tmExternalLeading) / scaled_font->em_square;
936  extents.max_x_advance = (double)(metrics.tmMaxCharWidth) / scaled_font->em_square;
937  extents.max_y_advance = 0;
938 
939  }
940 
941  scaled_font->is_bitmap = !(metrics.tmPitchAndFamily & TMPF_VECTOR);
942 
943  /* Need to determine if this is a Type 1 font for the special
944  * handling in _text_to_glyphs. Unlike TrueType or OpenType,
945  * Type1 fonts do not have a "cmap" table (or any other table).
946  * However GetFontData() will retrieve a Type1 font when
947  * requesting that GetFontData() retrieve data from the start of
948  * the file. This is to distinguish Type1 from stroke fonts such
949  * as "Script" and "Modern". The TMPF_TRUETYPE test is redundant
950  * but improves performance for the most common fonts.
951  */
952  scaled_font->is_type1 = FALSE;
953  if (!(metrics.tmPitchAndFamily & TMPF_TRUETYPE) &&
954  (metrics.tmPitchAndFamily & TMPF_VECTOR))
955  {
956  if ((GetFontData (hdc, CMAP_TAG, 0, NULL, 0) == GDI_ERROR) &&
957  (GetFontData (hdc, 0, 0, NULL, 0) != GDI_ERROR))
958  {
959  scaled_font->is_type1 = TRUE;
960  }
961  }
962 
963  return _cairo_scaled_font_set_metrics (&scaled_font->base, &extents);
964 }
965 
966 static cairo_status_t
968  cairo_scaled_glyph_t *scaled_glyph)
969 {
970  static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } };
971  GLYPHMETRICS metrics;
974  HDC hdc;
975 
977  assert (hdc != NULL);
978 
979  if (scaled_font->is_bitmap) {
980  /* GetGlyphOutline will not work. Assume that the glyph does not extend outside the font box. */
981  cairo_font_extents_t font_extents;
982  INT width = 0;
983  UINT charIndex = _cairo_scaled_glyph_index (scaled_glyph);
984 
985  cairo_scaled_font_extents (&scaled_font->base, &font_extents);
986 
988  if (status)
989  return status;
990 
991  if (!GetCharWidth32(hdc, charIndex, charIndex, &width)) {
992  status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_init_glyph_metrics:GetCharWidth32");
993  width = 0;
994  }
995  cairo_win32_scaled_font_done_font (&scaled_font->base);
996  if (status)
997  return status;
998 
999  extents.x_bearing = 0;
1000  extents.y_bearing = scaled_font->base.ctm.yy * (-font_extents.ascent / scaled_font->y_scale);
1001  extents.width = width / (WIN32_FONT_LOGICAL_SCALE * scaled_font->x_scale);
1002  extents.height = scaled_font->base.ctm.yy * (font_extents.ascent + font_extents.descent) / scaled_font->y_scale;
1003  extents.x_advance = extents.width;
1004  extents.y_advance = 0;
1005  } else if (scaled_font->preserve_axes && scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF) {
1006  /* If we aren't rotating / skewing the axes, then we get the metrics
1007  * from the GDI in device space and convert to font space.
1008  */
1010  if (status)
1011  return status;
1012 
1013  if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
1014  GGO_METRICS | GGO_GLYPH_INDEX,
1015  &metrics, 0, NULL, &matrix) == GDI_ERROR) {
1016  memset (&metrics, 0, sizeof (GLYPHMETRICS));
1017  } else {
1018  if (metrics.gmBlackBoxX > 0 && scaled_font->base.options.antialias != CAIRO_ANTIALIAS_NONE) {
1019  /* The bounding box reported by Windows supposedly contains the glyph's "black" area;
1020  * however, antialiasing (especially with ClearType) means that the actual image that
1021  * needs to be rendered may "bleed" into the adjacent pixels, mainly on the right side.
1022  * To avoid clipping the glyphs when drawn by _cairo_surface_fallback_show_glyphs,
1023  * for example, or other code that uses glyph extents to determine the area to update,
1024  * we add a pixel of "slop" to left side of the nominal "black" area returned by GDI,
1025  * and two pixels to the right (as tests show some glyphs bleed into this column).
1026  */
1027  metrics.gmptGlyphOrigin.x -= 1;
1028  metrics.gmBlackBoxX += 3;
1029  }
1030  }
1031  cairo_win32_scaled_font_done_font (&scaled_font->base);
1032 
1033  if (scaled_font->swap_axes) {
1034  extents.x_bearing = - metrics.gmptGlyphOrigin.y / scaled_font->y_scale;
1035  extents.y_bearing = metrics.gmptGlyphOrigin.x / scaled_font->x_scale;
1036  extents.width = metrics.gmBlackBoxY / scaled_font->y_scale;
1037  extents.height = metrics.gmBlackBoxX / scaled_font->x_scale;
1038  extents.x_advance = metrics.gmCellIncY / scaled_font->x_scale;
1039  extents.y_advance = metrics.gmCellIncX / scaled_font->y_scale;
1040  } else {
1041  extents.x_bearing = metrics.gmptGlyphOrigin.x / scaled_font->x_scale;
1042  extents.y_bearing = - metrics.gmptGlyphOrigin.y / scaled_font->y_scale;
1043  extents.width = metrics.gmBlackBoxX / scaled_font->x_scale;
1044  extents.height = metrics.gmBlackBoxY / scaled_font->y_scale;
1045  extents.x_advance = metrics.gmCellIncX / scaled_font->x_scale;
1046  extents.y_advance = metrics.gmCellIncY / scaled_font->y_scale;
1047  }
1048 
1049  if (scaled_font->swap_x) {
1050  extents.x_bearing = (- extents.x_bearing - extents.width);
1051  extents.x_advance = - extents.x_advance;
1052  }
1053 
1054  if (scaled_font->swap_y) {
1055  extents.y_bearing = (- extents.y_bearing - extents.height);
1056  extents.y_advance = - extents.y_advance;
1057  }
1058  } else {
1059  /* For all other transformations, we use the design metrics
1060  * of the font.
1061  */
1063  if (status)
1064  return status;
1065 
1066  if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
1067  GGO_METRICS | GGO_GLYPH_INDEX,
1068  &metrics, 0, NULL, &matrix) == GDI_ERROR) {
1069  memset (&metrics, 0, sizeof (GLYPHMETRICS));
1070  }
1072 
1073  extents.x_bearing = (double)metrics.gmptGlyphOrigin.x / scaled_font->em_square;
1074  extents.y_bearing = - (double)metrics.gmptGlyphOrigin.y / scaled_font->em_square;
1075  extents.width = (double)metrics.gmBlackBoxX / scaled_font->em_square;
1076  extents.height = (double)metrics.gmBlackBoxY / scaled_font->em_square;
1077  extents.x_advance = (double)metrics.gmCellIncX / scaled_font->em_square;
1078  extents.y_advance = (double)metrics.gmCellIncY / scaled_font->em_square;
1079  }
1080 
1081  _cairo_scaled_glyph_set_metrics (scaled_glyph,
1082  &scaled_font->base,
1083  &extents);
1084 
1085  return CAIRO_STATUS_SUCCESS;
1086 }
1087 
1088 /* Not currently used code, but may be useful in the future if we add
1089  * back the capability to the scaled font backend interface to get the
1090  * actual device space bbox rather than computing it from the
1091  * font-space metrics.
1092  */
1093 #if 0
1094 static cairo_status_t
1095 _cairo_win32_scaled_font_glyph_bbox (void *abstract_font,
1096  const cairo_glyph_t *glyphs,
1097  int num_glyphs,
1098  cairo_box_t *bbox)
1099 {
1100  static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } };
1101  cairo_win32_scaled_font_t *scaled_font = abstract_font;
1102  int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
1103 
1104  if (num_glyphs > 0) {
1105  HDC hdc;
1106  GLYPHMETRICS metrics;
1108  int i;
1109 
1110  hdc = _get_global_font_dc ();
1111  assert (hdc != NULL);
1112 
1114  if (status)
1115  return status;
1116 
1117  for (i = 0; i < num_glyphs; i++) {
1118  int x = _cairo_lround (glyphs[i].x);
1119  int y = _cairo_lround (glyphs[i].y);
1120 
1121  GetGlyphOutlineW (hdc, glyphs[i].index, GGO_METRICS | GGO_GLYPH_INDEX,
1122  &metrics, 0, NULL, &matrix);
1123 
1124  if (i == 0 || x1 > x + metrics.gmptGlyphOrigin.x)
1125  x1 = x + metrics.gmptGlyphOrigin.x;
1126  if (i == 0 || y1 > y - metrics.gmptGlyphOrigin.y)
1127  y1 = y - metrics.gmptGlyphOrigin.y;
1128  if (i == 0 || x2 < x + metrics.gmptGlyphOrigin.x + (int)metrics.gmBlackBoxX)
1129  x2 = x + metrics.gmptGlyphOrigin.x + (int)metrics.gmBlackBoxX;
1130  if (i == 0 || y2 < y - metrics.gmptGlyphOrigin.y + (int)metrics.gmBlackBoxY)
1131  y2 = y - metrics.gmptGlyphOrigin.y + (int)metrics.gmBlackBoxY;
1132  }
1133 
1134  cairo_win32_scaled_font_done_font (&scaled_font->base);
1135  }
1136 
1137  bbox->p1.x = _cairo_fixed_from_int (x1);
1138  bbox->p1.y = _cairo_fixed_from_int (y1);
1139  bbox->p2.x = _cairo_fixed_from_int (x2);
1140  bbox->p2.y = _cairo_fixed_from_int (y2);
1141 
1142  return CAIRO_STATUS_SUCCESS;
1143 }
1144 #endif
1145 
1146 typedef struct {
1147  cairo_win32_scaled_font_t *scaled_font;
1148  HDC hdc;
1149 
1151  cairo_array_t dx;
1152 
1153  int start_x;
1154  int last_x;
1155  int last_y;
1157 
1158 static void
1160  cairo_win32_scaled_font_t *scaled_font,
1161  HDC hdc)
1162 {
1163  state->hdc = hdc;
1164  state->scaled_font = scaled_font;
1165 
1166  _cairo_array_init (&state->glyphs, sizeof (WCHAR));
1167  _cairo_array_init (&state->dx, sizeof (int));
1168 }
1169 
1170 static cairo_status_t
1172 {
1174  int dx = 0;
1175  WCHAR * elements;
1176  int * dx_elements;
1177 
1178  status = _cairo_array_append (&state->dx, &dx);
1179  if (status)
1180  return status;
1181 
1182  elements = _cairo_array_index (&state->glyphs, 0);
1183  dx_elements = _cairo_array_index (&state->dx, 0);
1184  if (!ExtTextOutW (state->hdc,
1185  state->start_x, state->last_y,
1186  ETO_GLYPH_INDEX,
1187  NULL,
1188  elements,
1189  state->glyphs.num_elements,
1190  dx_elements)) {
1191  return _cairo_win32_print_gdi_error ("_flush_glyphs");
1192  }
1193 
1194  _cairo_array_truncate (&state->glyphs, 0);
1195  _cairo_array_truncate (&state->dx, 0);
1196 
1197  return CAIRO_STATUS_SUCCESS;
1198 }
1199 
1200 static cairo_status_t
1202  unsigned long index,
1203  double device_x,
1204  double device_y)
1205 {
1207  double user_x = device_x;
1208  double user_y = device_y;
1209  WCHAR glyph_index = index;
1210  int logical_x, logical_y;
1211 
1212  cairo_matrix_transform_point (&state->scaled_font->device_to_logical, &user_x, &user_y);
1213 
1214  logical_x = _cairo_lround (user_x);
1215  logical_y = _cairo_lround (user_y);
1216 
1217  if (state->glyphs.num_elements > 0) {
1218  int dx;
1219 
1220  if (logical_y != state->last_y) {
1222  if (status)
1223  return status;
1224  state->start_x = logical_x;
1225  } else {
1226  dx = logical_x - state->last_x;
1227  status = _cairo_array_append (&state->dx, &dx);
1228  if (status)
1229  return status;
1230  }
1231  } else {
1232  state->start_x = logical_x;
1233  }
1234 
1235  state->last_x = logical_x;
1236  state->last_y = logical_y;
1237 
1239  if (status)
1240  return status;
1241 
1242  return CAIRO_STATUS_SUCCESS;
1243 }
1244 
1245 static cairo_status_t
1247 {
1249 
1251 
1252  _cairo_array_fini (&state->glyphs);
1253  _cairo_array_fini (&state->dx);
1254 
1255  return status;
1256 }
1257 
1258 static cairo_status_t
1260  cairo_win32_scaled_font_t *scaled_font,
1261  COLORREF color,
1262  int x_offset,
1263  int y_offset,
1264  const cairo_glyph_t *glyphs,
1265  int num_glyphs)
1266 {
1268  cairo_status_t status, status2;
1269  int i;
1270 
1271  if (!SaveDC (surface->dc))
1272  return _cairo_win32_print_gdi_error ("_draw_glyphs_on_surface:SaveDC");
1273 
1274  status = cairo_win32_scaled_font_select_font (&scaled_font->base, surface->dc);
1275  if (status)
1276  goto FAIL1;
1277 
1278  SetTextColor (surface->dc, color);
1279  SetTextAlign (surface->dc, TA_BASELINE | TA_LEFT);
1280  SetBkMode (surface->dc, TRANSPARENT);
1281 
1282  _start_glyphs (&state, scaled_font, surface->dc);
1283 
1284  for (i = 0; i < num_glyphs; i++) {
1286  glyphs[i].x - x_offset, glyphs[i].y - y_offset);
1287  if (status)
1288  goto FAIL2;
1289  }
1290 
1291  FAIL2:
1292  status2 = _finish_glyphs (&state);
1294  status = status2;
1295 
1296  cairo_win32_scaled_font_done_font (&scaled_font->base);
1297  FAIL1:
1298  RestoreDC (surface->dc, -1);
1299 
1300  return status;
1301 }
1302 
1303 static cairo_int_status_t
1305  cairo_scaled_glyph_t *scaled_glyph,
1307 {
1308  cairo_win32_scaled_font_t *scaled_font = abstract_font;
1310 
1311  if ((info & CAIRO_SCALED_GLYPH_INFO_METRICS) != 0) {
1312  status = _cairo_win32_scaled_font_init_glyph_metrics (scaled_font, scaled_glyph);
1313  if (status)
1314  return status;
1315  }
1316 
1318  status = _cairo_win32_scaled_font_init_glyph_surface (scaled_font, scaled_glyph);
1319  if (status)
1320  return status;
1321  }
1322 
1323  if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0) {
1324  status = _cairo_win32_scaled_font_init_glyph_path (scaled_font, scaled_glyph);
1325  if (status)
1326  return status;
1327  }
1328 
1329  return CAIRO_STATUS_SUCCESS;
1330 }
1331 
1332 static cairo_int_status_t
1334  unsigned long tag,
1335  long offset,
1336  unsigned char *buffer,
1337  unsigned long *length)
1338 {
1339  cairo_win32_scaled_font_t *scaled_font = abstract_font;
1340  HDC hdc;
1342  DWORD ret;
1343 
1344  hdc = _get_global_font_dc ();
1345  assert (hdc != NULL);
1346 
1347  tag = (tag&0x000000ff)<<24 | (tag&0x0000ff00)<<8 | (tag&0x00ff0000)>>8 | (tag&0xff000000)>>24;
1349  if (status)
1350  return status;
1351 
1352  ret = GetFontData (hdc, tag, offset, buffer, *length);
1353  if (ret == GDI_ERROR || (buffer && ret != *length))
1355  else
1356  *length = ret;
1357 
1358  cairo_win32_scaled_font_done_font (&scaled_font->base);
1359 
1360  return status;
1361 }
1362 
1363 static cairo_int_status_t
1365  unsigned long index,
1366  uint32_t *ucs4)
1367 {
1368  cairo_win32_scaled_font_t *scaled_font = abstract_font;
1369  GLYPHSET *glyph_set;
1370  uint16_t *utf16 = NULL;
1371  WORD *glyph_indices = NULL;
1372  HDC hdc = NULL;
1373  int res;
1374  unsigned int i, j, num_glyphs;
1376 
1377  hdc = _get_global_font_dc ();
1378  assert (hdc != NULL);
1379 
1381  if (status)
1382  return status;
1383 
1384  res = GetFontUnicodeRanges(hdc, NULL);
1385  if (res == 0) {
1387  "_cairo_win32_scaled_font_index_to_ucs4:GetFontUnicodeRanges");
1388  goto exit1;
1389  }
1390 
1391  glyph_set = _cairo_malloc (res);
1392  if (glyph_set == NULL) {
1394  goto exit1;
1395  }
1396 
1397  res = GetFontUnicodeRanges(hdc, glyph_set);
1398  if (res == 0) {
1400  "_cairo_win32_scaled_font_index_to_ucs4:GetFontUnicodeRanges");
1401  goto exit1;
1402  }
1403 
1404  *ucs4 = (uint32_t) -1;
1405  for (i = 0; i < glyph_set->cRanges; i++) {
1406  num_glyphs = glyph_set->ranges[i].cGlyphs;
1407 
1408  utf16 = _cairo_malloc_ab (num_glyphs + 1, sizeof (uint16_t));
1409  if (utf16 == NULL) {
1411  goto exit1;
1412  }
1413 
1414  glyph_indices = _cairo_malloc_ab (num_glyphs + 1, sizeof (WORD));
1415  if (glyph_indices == NULL) {
1417  goto exit2;
1418  }
1419 
1420  for (j = 0; j < num_glyphs; j++)
1421  utf16[j] = glyph_set->ranges[i].wcLow + j;
1422  utf16[j] = 0;
1423 
1424  if (GetGlyphIndicesW (hdc, utf16, num_glyphs, glyph_indices, 0) == GDI_ERROR) {
1426  "_cairo_win32_scaled_font_index_to_ucs4:GetGlyphIndicesW");
1427  goto exit2;
1428  }
1429 
1430  for (j = 0; j < num_glyphs; j++) {
1431  if (glyph_indices[j] == index) {
1432  *ucs4 = utf16[j];
1433  goto exit2;
1434  }
1435  }
1436 
1437  free (glyph_indices);
1438  glyph_indices = NULL;
1439  free (utf16);
1440  utf16 = NULL;
1441  }
1442 
1443 exit2:
1444  free (glyph_indices);
1445  free (utf16);
1446  free (glyph_set);
1447 exit1:
1448  cairo_win32_scaled_font_done_font (&scaled_font->base);
1449 
1450  return status;
1451 }
1452 
1453 static cairo_int_status_t
1455  cairo_bool_t *is_synthetic)
1456 {
1457  cairo_win32_scaled_font_t *scaled_font = abstract_font;
1459  int weight;
1460  cairo_bool_t bold;
1462 
1463  *is_synthetic = FALSE;
1464  status = _cairo_truetype_get_style (&scaled_font->base,
1465  &weight,
1466  &bold,
1467  &italic);
1468  /* If this doesn't work assume it is not synthetic to avoid
1469  * unnecessary subsetting fallbacks. */
1471  return CAIRO_STATUS_SUCCESS;
1472 
1473  if (scaled_font->logfont.lfWeight != weight ||
1474  scaled_font->logfont.lfItalic != italic)
1475  *is_synthetic = TRUE;
1476 
1477  return CAIRO_STATUS_SUCCESS;
1478 }
1479 
1480 static cairo_int_status_t
1482  char **glyph_names,
1483  int num_glyph_names,
1484  unsigned long glyph_index,
1485  unsigned long *glyph_array_index)
1486 {
1487  cairo_win32_scaled_font_t *scaled_font = abstract_font;
1488  int i;
1489 
1490  /* Windows puts .notdef at index 0 then numbers the remaining
1491  * glyphs starting from 1 in the order they appear in the font. */
1492 
1493  /* Find the position of .notdef in the list of glyph names. We
1494  * only need to do this once per scaled font. */
1495  if (! scaled_font->has_type1_notdef_index) {
1496  for (i = 0; i < num_glyph_names; i++) {
1497  if (strcmp (glyph_names[i], ".notdef") == 0) {
1498  scaled_font->type1_notdef_index = i;
1499  scaled_font->has_type1_notdef_index = TRUE;
1500  break;
1501  }
1502  }
1503  if (! scaled_font->has_type1_notdef_index)
1505  }
1506 
1507  /* Once we know the position of .notdef the position of any glyph
1508  * in the font can easily be obtained. */
1509  if (glyph_index == 0)
1510  *glyph_array_index = scaled_font->type1_notdef_index;
1511  else if (glyph_index <= scaled_font->type1_notdef_index)
1512  *glyph_array_index = glyph_index - 1;
1513  else if (glyph_index < (unsigned long)num_glyph_names)
1514  *glyph_array_index = glyph_index;
1515  else
1517 
1518  return CAIRO_STATUS_SUCCESS;
1519 }
1520 
1521 static cairo_int_status_t
1523  long offset,
1524  unsigned char *buffer,
1525  unsigned long *length)
1526 {
1527  cairo_win32_scaled_font_t *scaled_font = abstract_font;
1528 
1529  if (! scaled_font->is_type1)
1531 
1532  /* Using the tag 0 retrieves the entire font file. This works with
1533  * Type 1 fonts as well as TTF/OTF fonts. */
1535  0,
1536  offset,
1537  buffer,
1538  length);
1539 }
1540 
1541 static cairo_surface_t *
1543  int quality)
1544 {
1547  int i, j;
1548 
1550  if (unlikely (glyph->base.status))
1551  return &glyph->base;
1552 
1554  /* Duplicate the green channel of a 4-channel mask into the
1555  * alpha channel, then invert the whole mask.
1556  */
1559  glyph->width, glyph->height);
1560  if (likely (mask->base.status == CAIRO_STATUS_SUCCESS)) {
1561  for (i = 0; i < glyph->height; i++) {
1562  uint32_t *p = (uint32_t *) (glyph->data + i * glyph->stride);
1563  uint32_t *q = (uint32_t *) (mask->data + i * mask->stride);
1564 
1565  for (j = 0; j < glyph->width; j++) {
1566  *q++ = 0xffffffff ^ (*p | ((*p & 0x0000ff00) << 16));
1567  p++;
1568  }
1569  }
1570  }
1571  } else {
1572  /* Compute an alpha-mask from a using the green channel of a
1573  * (presumed monochrome) RGB24 image.
1574  */
1577  glyph->width, glyph->height);
1578  if (likely (mask->base.status == CAIRO_STATUS_SUCCESS)) {
1579  for (i = 0; i < glyph->height; i++) {
1580  uint32_t *p = (uint32_t *) (glyph->data + i * glyph->stride);
1581  uint8_t *q = (uint8_t *) (mask->data + i * mask->stride);
1582 
1583  for (j = 0; j < glyph->width; j++)
1584  *q++ = 255 - ((*p++ & 0x0000ff00) >> 8);
1585  }
1586  }
1587  }
1588 
1590  return &mask->base;
1591 }
1592 
1593 static cairo_status_t
1595  cairo_scaled_glyph_t *scaled_glyph)
1596 {
1601  int width, height;
1602  int x1, y1, x2, y2;
1603 
1604  x1 = _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.x);
1605  y1 = _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.y);
1606  x2 = _cairo_fixed_integer_ceil (scaled_glyph->bbox.p2.x);
1607  y2 = _cairo_fixed_integer_ceil (scaled_glyph->bbox.p2.y);
1608  width = x2 - x1;
1609  height = y2 - y1;
1610 
1612  width, height);
1615  if (status)
1616  goto FAIL;
1617 
1618  glyph.index = _cairo_scaled_glyph_index (scaled_glyph);
1619  glyph.x = -x1;
1620  glyph.y = -y1;
1622  scaled_font, RGB(0,0,0),
1623  0, 0, &glyph, 1);
1624  if (status)
1625  goto FAIL;
1626 
1627  image = _compute_mask (surface, scaled_font->quality);
1628  status = image->status;
1629  if (status)
1630  goto FAIL;
1631 
1633  _cairo_scaled_glyph_set_surface (scaled_glyph,
1634  &scaled_font->base,
1636 
1637  FAIL:
1639 
1640  return status;
1641 }
1642 
1643 static void
1645  FIXED Fx, FIXED Fy,
1647 {
1648  double x = Fx.value + Fx.fract / 65536.0;
1649  double y = Fy.value + Fy.fract / 65536.0;
1652  *fy = _cairo_fixed_from_double (y);
1653 }
1654 
1655 static cairo_status_t
1657  cairo_scaled_glyph_t *scaled_glyph)
1658 {
1659  static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, -1 } };
1661  GLYPHMETRICS metrics;
1662  HDC hdc;
1663  DWORD bytesGlyph;
1664  unsigned char *buffer, *ptr;
1667  cairo_fixed_t x, y;
1668 
1669  if (scaled_font->is_bitmap)
1671 
1672  hdc = _get_global_font_dc ();
1673  assert (hdc != NULL);
1674 
1676  if (!path)
1678 
1679  if (scaled_font->base.options.hint_style == CAIRO_HINT_STYLE_NONE) {
1681  transform = scaled_font->base.scale;
1682  cairo_matrix_scale (&transform, 1.0/scaled_font->em_square, 1.0/scaled_font->em_square);
1683  } else {
1686  }
1687  if (status)
1688  goto CLEANUP_PATH;
1689 
1690  bytesGlyph = GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
1691  GGO_NATIVE | GGO_GLYPH_INDEX,
1692  &metrics, 0, NULL, &matrix);
1693 
1694  if (bytesGlyph == GDI_ERROR) {
1695  status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path");
1696  goto CLEANUP_FONT;
1697  }
1698 
1699  ptr = buffer = _cairo_malloc (bytesGlyph);
1700  if (!buffer && bytesGlyph != 0) {
1702  goto CLEANUP_FONT;
1703  }
1704 
1705  if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
1706  GGO_NATIVE | GGO_GLYPH_INDEX,
1707  &metrics, bytesGlyph, buffer, &matrix) == GDI_ERROR) {
1708  status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_glyph_path");
1709  goto CLEANUP_BUFFER;
1710  }
1711 
1712  while (ptr < buffer + bytesGlyph) {
1713  TTPOLYGONHEADER *header = (TTPOLYGONHEADER *)ptr;
1714  unsigned char *endPoly = ptr + header->cb;
1715 
1716  ptr += sizeof (TTPOLYGONHEADER);
1717 
1719  header->pfxStart.x,
1720  header->pfxStart.y,
1721  &x, &y);
1723  if (status)
1724  goto CLEANUP_BUFFER;
1725 
1726  while (ptr < endPoly) {
1727  TTPOLYCURVE *curve = (TTPOLYCURVE *)ptr;
1728  POINTFX *points = curve->apfx;
1729  int i;
1730  switch (curve->wType) {
1731  case TT_PRIM_LINE:
1732  for (i = 0; i < curve->cpfx; i++) {
1734  points[i].x,
1735  points[i].y,
1736  &x, &y);
1738  if (status)
1739  goto CLEANUP_BUFFER;
1740  }
1741  break;
1742  case TT_PRIM_QSPLINE:
1743  for (i = 0; i < curve->cpfx - 1; i++) {
1744  cairo_fixed_t p1x, p1y, p2x, p2y, cx, cy, c1x, c1y, c2x, c2y;
1745  if (! _cairo_path_fixed_get_current_point (path, &p1x, &p1y))
1746  goto CLEANUP_BUFFER;
1748  points[i].x,
1749  points[i].y,
1750  &cx, &cy);
1751 
1752  if (i + 1 == curve->cpfx - 1) {
1754  points[i + 1].x,
1755  points[i + 1].y,
1756  &p2x, &p2y);
1757  } else {
1758  /* records with more than one curve use interpolation for
1759  control points, per http://support.microsoft.com/kb/q87115/ */
1761  points[i + 1].x,
1762  points[i + 1].y,
1763  &x, &y);
1764  p2x = (cx + x) / 2;
1765  p2y = (cy + y) / 2;
1766  }
1767 
1768  c1x = 2 * cx / 3 + p1x / 3;
1769  c1y = 2 * cy / 3 + p1y / 3;
1770  c2x = 2 * cx / 3 + p2x / 3;
1771  c2y = 2 * cy / 3 + p2y / 3;
1772 
1773  status = _cairo_path_fixed_curve_to (path, c1x, c1y, c2x, c2y, p2x, p2y);
1774  if (status)
1775  goto CLEANUP_BUFFER;
1776  }
1777  break;
1778  case TT_PRIM_CSPLINE:
1779  for (i = 0; i < curve->cpfx - 2; i += 2) {
1780  cairo_fixed_t x1, y1, x2, y2;
1782  points[i].x,
1783  points[i].y,
1784  &x, &y);
1786  points[i + 1].x,
1787  points[i + 1].y,
1788  &x1, &y1);
1790  points[i + 2].x,
1791  points[i + 2].y,
1792  &x2, &y2);
1794  if (status)
1795  goto CLEANUP_BUFFER;
1796  }
1797  break;
1798  }
1799  ptr += sizeof(TTPOLYCURVE) + sizeof (POINTFX) * (curve->cpfx - 1);
1800  }
1802  if (status)
1803  goto CLEANUP_BUFFER;
1804  }
1805 
1806  _cairo_scaled_glyph_set_path (scaled_glyph,
1807  &scaled_font->base,
1808  path);
1809 
1810  CLEANUP_BUFFER:
1811  free (buffer);
1812 
1813  CLEANUP_FONT:
1814  if (scaled_font->base.options.hint_style == CAIRO_HINT_STYLE_NONE)
1816  else
1817  cairo_win32_scaled_font_done_font (&scaled_font->base);
1818 
1819  CLEANUP_PATH:
1822 
1823  return status;
1824 }
1825 
1830  NULL, /* _cairo_win32_scaled_font_text_to_glyphs, FIXME */
1837 };
1838 
1839 /* #cairo_win32_font_face_t */
1840 
1842 
1843 /* If hfont is non-%NULL then logfont->lfHeight must be -S for some S,
1844  * logfont->lfWidth, logfont->lfEscapement, logfont->lfOrientation must
1845  * all be 0, and hfont is the result of calling CreateFontIndirectW on
1846  * logfont.
1847  */
1848 struct _cairo_win32_font_face {
1850  LOGFONTW logfont;
1851  HFONT hfont;
1852 };
1853 
1854 /* We maintain a hash table from LOGFONT,HFONT => #cairo_font_face_t.
1855  * The primary purpose of this mapping is to provide unique
1856  * #cairo_font_face_t values so that our cache and mapping from
1857  * #cairo_font_face_t => #cairo_scaled_font_t works. Once the
1858  * corresponding #cairo_font_face_t objects fall out of downstream
1859  * caches, we don't need them in this hash table anymore.
1860  *
1861  * Modifications to this hash table are protected by
1862  * _cairo_win32_font_face_mutex.
1863  */
1864 
1866 
1867 static int
1868 _cairo_win32_font_face_keys_equal (const void *key_a,
1869  const void *key_b);
1870 
1871 static void
1873 {
1875 
1876  /* We manually acquire the lock rather than calling
1877  * _cairo_win32_font_face_hash_table_lock simply to avoid creating
1878  * the table only to destroy it again. */
1879  CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
1882  CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
1883 
1884  if (hash_table != NULL)
1886 }
1887 
1888 static cairo_hash_table_t *
1890 {
1891  CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
1892 
1894  {
1897 
1899  CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
1901  return NULL;
1902  }
1903  }
1904 
1906 }
1907 
1908 static void
1910 {
1911  CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
1912 }
1913 
1914 static cairo_bool_t
1915 _cairo_win32_font_face_destroy (void *abstract_face)
1916 {
1917  cairo_win32_font_face_t *font_face = abstract_face;
1919 
1921  /* All created objects must have been mapped in the hash table. */
1922  assert (hash_table != NULL);
1923 
1924  if (! _cairo_reference_count_dec_and_test (&font_face->base.ref_count)) {
1925  /* somebody recreated the font whilst we waited for the lock */
1927  return FALSE;
1928  }
1929 
1930  /* Font faces in SUCCESS status are guaranteed to be in the
1931  * hashtable. Font faces in an error status are removed from the
1932  * hashtable if they are found during a lookup, thus they should
1933  * only be removed if they are in the hashtable. */
1934  if (likely (font_face->base.status == CAIRO_STATUS_SUCCESS) ||
1935  _cairo_hash_table_lookup (hash_table, &font_face->base.hash_entry) == font_face)
1936  _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
1937 
1939  return TRUE;
1940 }
1941 
1942 static void
1944  LOGFONTW *logfont,
1945  HFONT font)
1946 {
1947  unsigned long hash = _CAIRO_HASH_INIT_VALUE;
1948 
1949  key->logfont = *logfont;
1950  key->hfont = font;
1951 
1952  hash = _cairo_hash_bytes (0, logfont->lfFaceName, 2*wcslen(logfont->lfFaceName));
1953  hash = _cairo_hash_bytes (hash, &logfont->lfWeight, sizeof(logfont->lfWeight));
1954  hash = _cairo_hash_bytes (hash, &logfont->lfItalic, sizeof(logfont->lfItalic));
1955 
1956  key->base.hash_entry.hash = hash;
1957 }
1958 
1959 static int
1961  const void *key_b)
1962 {
1963  const cairo_win32_font_face_t *face_a = key_a;
1964  const cairo_win32_font_face_t *face_b = key_b;
1965 
1966  if (face_a->logfont.lfWeight == face_b->logfont.lfWeight &&
1967  face_a->logfont.lfItalic == face_b->logfont.lfItalic &&
1968  face_a->logfont.lfUnderline == face_b->logfont.lfUnderline &&
1969  face_a->logfont.lfStrikeOut == face_b->logfont.lfStrikeOut &&
1970  face_a->logfont.lfCharSet == face_b->logfont.lfCharSet &&
1971  face_a->logfont.lfOutPrecision == face_b->logfont.lfOutPrecision &&
1972  face_a->logfont.lfClipPrecision == face_b->logfont.lfClipPrecision &&
1973  face_a->logfont.lfPitchAndFamily == face_b->logfont.lfPitchAndFamily &&
1974  (wcscmp (face_a->logfont.lfFaceName, face_b->logfont.lfFaceName) == 0))
1975  return TRUE;
1976  else
1977  return FALSE;
1978 }
1979 
1980 /* implement the platform-specific interface */
1981 
1982 static cairo_bool_t
1984 {
1985  return matrix->xx == scale && matrix->yy == scale &&
1986  matrix->xy == 0. && matrix->yx == 0. &&
1987  matrix->x0 == 0. && matrix->y0 == 0.;
1988 }
1989 
1990 static cairo_status_t
1992  const cairo_matrix_t *font_matrix,
1993  const cairo_matrix_t *ctm,
1996 {
1997  HFONT hfont = NULL;
1998 
1999  cairo_win32_font_face_t *font_face = abstract_face;
2000 
2001  if (font_face->hfont) {
2002  /* Check whether it's OK to go ahead and use the font-face's HFONT. */
2003  if (_is_scale (ctm, 1.) &&
2004  _is_scale (font_matrix, -font_face->logfont.lfHeight)) {
2005  hfont = font_face->hfont;
2006  }
2007  }
2008 
2009  return _win32_scaled_font_create (&font_face->logfont,
2010  hfont,
2011  &font_face->base,
2012  font_matrix, ctm, options,
2013  font);
2014 }
2015 
2021 };
2022 
2023 /**
2024  * cairo_win32_font_face_create_for_logfontw_hfont:
2025  * @logfont: A #LOGFONTW structure specifying the font to use.
2026  * If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement
2027  * fields of this structure are ignored. Otherwise lfWidth, lfOrientation and
2028  * lfEscapement must be zero.
2029  * @font: An #HFONT that can be used when the font matrix is a scale by
2030  * -lfHeight and the CTM is identity.
2031  *
2032  * Creates a new font for the Win32 font backend based on a
2033  * #LOGFONT. This font can then be used with
2034  * cairo_set_font_face() or cairo_scaled_font_create().
2035  * The #cairo_scaled_font_t
2036  * returned from cairo_scaled_font_create() is also for the Win32 backend
2037  * and can be used with functions such as cairo_win32_scaled_font_select_font().
2038  *
2039  * Return value: a newly created #cairo_font_face_t. Free with
2040  * cairo_font_face_destroy() when you are done using it.
2041  *
2042  * Since: 1.6
2043  **/
2046 {
2050 
2052  if (unlikely (hash_table == NULL)) {
2055  }
2056 
2058 
2059  /* Return existing unscaled font if it exists in the hash table. */
2061  &key.base.hash_entry);
2062  if (font_face != NULL) {
2063  if (font_face->base.status == CAIRO_STATUS_SUCCESS) {
2066  return &font_face->base;
2067  }
2068 
2069  /* remove the bad font from the hash table */
2070  _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
2071  }
2072 
2073  /* Otherwise create it and insert into hash table. */
2075  if (!font_face) {
2077  goto FAIL;
2078  }
2079 
2082 
2083  assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
2085  &font_face->base.hash_entry);
2086  if (unlikely (status))
2087  goto FAIL;
2088 
2090  return &font_face->base;
2091 
2092 FAIL:
2095 }
2096 
2097 /**
2098  * cairo_win32_font_face_create_for_logfontw:
2099  * @logfont: A #LOGFONTW structure specifying the font to use.
2100  * The lfHeight, lfWidth, lfOrientation and lfEscapement
2101  * fields of this structure are ignored.
2102  *
2103  * Creates a new font for the Win32 font backend based on a
2104  * #LOGFONT. This font can then be used with
2105  * cairo_set_font_face() or cairo_scaled_font_create().
2106  * The #cairo_scaled_font_t
2107  * returned from cairo_scaled_font_create() is also for the Win32 backend
2108  * and can be used with functions such as cairo_win32_scaled_font_select_font().
2109  *
2110  * Return value: a newly created #cairo_font_face_t. Free with
2111  * cairo_font_face_destroy() when you are done using it.
2112  *
2113  * Since: 1.0
2114  **/
2117 {
2119 }
2120 
2121 /**
2122  * cairo_win32_font_face_create_for_hfont:
2123  * @font: An #HFONT structure specifying the font to use.
2124  *
2125  * Creates a new font for the Win32 font backend based on a
2126  * #HFONT. This font can then be used with
2127  * cairo_set_font_face() or cairo_scaled_font_create().
2128  * The #cairo_scaled_font_t
2129  * returned from cairo_scaled_font_create() is also for the Win32 backend
2130  * and can be used with functions such as cairo_win32_scaled_font_select_font().
2131  *
2132  * Return value: a newly created #cairo_font_face_t. Free with
2133  * cairo_font_face_destroy() when you are done using it.
2134  *
2135  * Since: 1.2
2136  **/
2139 {
2140  LOGFONTW logfont;
2141  GetObjectW (font, sizeof(logfont), &logfont);
2142 
2143  if (logfont.lfEscapement != 0 || logfont.lfOrientation != 0 ||
2144  logfont.lfWidth != 0) {
2145  /* We can't use this font because that optimization requires that
2146  * lfEscapement, lfOrientation and lfWidth be zero. */
2147  font = NULL;
2148  }
2149 
2151 }
2152 
2153 static cairo_bool_t
2155 {
2156  return scaled_font->backend == &_cairo_win32_scaled_font_backend;
2157 }
2158 
2159 /**
2160  * cairo_win32_scaled_font_select_font:
2161  * @scaled_font: A #cairo_scaled_font_t from the Win32 font backend. Such an
2162  * object can be created with cairo_win32_font_face_create_for_logfontw().
2163  * @hdc: a device context
2164  *
2165  * Selects the font into the given device context and changes the
2166  * map mode and world transformation of the device context to match
2167  * that of the font. This function is intended for use when using
2168  * layout APIs such as Uniscribe to do text layout with the
2169  * cairo font. After finishing using the device context, you must call
2170  * cairo_win32_scaled_font_done_font() to release any resources allocated
2171  * by this function.
2172  *
2173  * See cairo_win32_scaled_font_get_metrics_factor() for converting logical
2174  * coordinates from the device context to font space.
2175  *
2176  * Normally, calls to SaveDC() and RestoreDC() would be made around
2177  * the use of this function to preserve the original graphics state.
2178  *
2179  * Return value: %CAIRO_STATUS_SUCCESS if the operation succeeded.
2180  * otherwise an error such as %CAIRO_STATUS_NO_MEMORY and
2181  * the device context is unchanged.
2182  *
2183  * Since: 1.0
2184  **/
2187  HDC hdc)
2188 {
2190  HFONT hfont;
2191  HFONT old_hfont = NULL;
2192  int old_mode;
2193 
2194  if (! _cairo_scaled_font_is_win32 (scaled_font)) {
2196  }
2197 
2198  if (scaled_font->status)
2199  return scaled_font->status;
2200 
2202  if (status)
2203  return status;
2204 
2205  old_hfont = SelectObject (hdc, hfont);
2206  if (!old_hfont)
2207  return _cairo_win32_print_gdi_error ("cairo_win32_scaled_font_select_font:SelectObject");
2208 
2209  old_mode = SetGraphicsMode (hdc, GM_ADVANCED);
2210  if (!old_mode) {
2211  status = _cairo_win32_print_gdi_error ("cairo_win32_scaled_font_select_font:SetGraphicsMode");
2212  SelectObject (hdc, old_hfont);
2213  return status;
2214  }
2215 
2217  if (status) {
2218  SetGraphicsMode (hdc, old_mode);
2219  SelectObject (hdc, old_hfont);
2220  return status;
2221  }
2222 
2223  SetMapMode (hdc, MM_TEXT);
2224 
2225  return CAIRO_STATUS_SUCCESS;
2226 }
2227 
2228 /**
2229  * cairo_win32_scaled_font_done_font:
2230  * @scaled_font: A scaled font from the Win32 font backend.
2231  *
2232  * Releases any resources allocated by cairo_win32_scaled_font_select_font()
2233  *
2234  * Since: 1.0
2235  **/
2236 void
2238 {
2239  if (! _cairo_scaled_font_is_win32 (scaled_font)) {
2241  }
2242 }
2243 
2244 /**
2245  * cairo_win32_scaled_font_get_metrics_factor:
2246  * @scaled_font: a scaled font from the Win32 font backend
2247  *
2248  * Gets a scale factor between logical coordinates in the coordinate
2249  * space used by cairo_win32_scaled_font_select_font() (that is, the
2250  * coordinate system used by the Windows functions to return metrics) and
2251  * font space coordinates.
2252  *
2253  * Return value: factor to multiply logical units by to get font space
2254  * coordinates.
2255  *
2256  * Since: 1.0
2257  **/
2258 double
2260 {
2261  if (! _cairo_scaled_font_is_win32 (scaled_font)) {
2263  return 1.;
2264  }
2265  return 1. / ((cairo_win32_scaled_font_t *)scaled_font)->logical_scale;
2266 }
2267 
2268 /**
2269  * cairo_win32_scaled_font_get_logical_to_device:
2270  * @scaled_font: a scaled font from the Win32 font backend
2271  * @logical_to_device: matrix to return
2272  *
2273  * Gets the transformation mapping the logical space used by @scaled_font
2274  * to device space.
2275  *
2276  * Since: 1.4
2277  **/
2278 void
2280  cairo_matrix_t *logical_to_device)
2281 {
2282  cairo_win32_scaled_font_t *win_font = (cairo_win32_scaled_font_t *)scaled_font;
2283  if (! _cairo_scaled_font_is_win32 (scaled_font)) {
2285  cairo_matrix_init_identity (logical_to_device);
2286  return;
2287  }
2288  *logical_to_device = win_font->logical_to_device;
2289 }
2290 
2291 /**
2292  * cairo_win32_scaled_font_get_device_to_logical:
2293  * @scaled_font: a scaled font from the Win32 font backend
2294  * @device_to_logical: matrix to return
2295  *
2296  * Gets the transformation mapping device space to the logical space
2297  * used by @scaled_font.
2298  *
2299  * Since: 1.4
2300  **/
2301 void
2303  cairo_matrix_t *device_to_logical)
2304 {
2305  cairo_win32_scaled_font_t *win_font = (cairo_win32_scaled_font_t *)scaled_font;
2306  if (! _cairo_scaled_font_is_win32 (scaled_font)) {
2308  cairo_matrix_init_identity (device_to_logical);
2309  return;
2310  }
2311  *device_to_logical = win_font->device_to_logical;
2312 }
2313 
2314 void
2316 {
2318 }
#define FAIL2(X1, X2)
Definition: __debug.h:68
#define FAIL1(X1)
Definition: __debug.h:67
#define FAIL3(X1, X2, X3)
Definition: __debug.h:69
q
Definition: afm2pl.c:2287
long * italic
Definition: afm2tfm.c:1034
#define sc
Definition: aptex-macros.h:57
#define state
Definition: aptex-macros.h:996
#define font
Definition: aptex-macros.h:175
#define width(a)
Definition: aptex-macros.h:198
#define height(a)
Definition: aptex-macros.h:200
static FT_Face font_face[65536]
Definition: aptex-src.c:20633
#define hash
Definition: aptex.h:388
size_t __cdecl wcslen(wchar_t const *_String)
int __cdecl wcscmp(wchar_t const *_String1, wchar_t const *_String2)
void _cairo_array_fini(cairo_array_t *array)
Definition: cairo-array.c:75
void * _cairo_array_index(cairo_array_t *array, unsigned int index)
Definition: cairo-array.c:166
void _cairo_array_truncate(cairo_array_t *array, unsigned int num_elements)
Definition: cairo-array.c:137
void _cairo_array_init(cairo_array_t *array, unsigned int element_size)
Definition: cairo-array.c:58
cairo_status_t _cairo_array_append(cairo_array_t *array, const void *element)
Definition: cairo-array.c:262
unsigned long _cairo_hash_bytes(unsigned long hash, const void *ptr, unsigned int length)
Definition: cairo-cache.c:329
cairo_status_t _cairo_error(cairo_status_t status)
Definition: cairo-error.c:65
enum _cairo_int_status cairo_int_status_t
#define _cairo_error_throw(status)
@ CAIRO_INT_STATUS_UNSUPPORTED
static cairo_fixed_t _cairo_fixed_from_int(int i)
static int _cairo_fixed_integer_floor(cairo_fixed_t f)
static int _cairo_fixed_integer_ceil(cairo_fixed_t f)
static cairo_fixed_t _cairo_fixed_from_double(double d)
int32_t cairo_fixed_t
const cairo_font_face_t _cairo_font_face_nil
void _cairo_font_face_init(cairo_font_face_t *font_face, const cairo_font_face_backend_t *backend)
cairo_font_face_t * cairo_font_face_reference(cairo_font_face_t *font_face)
cairo_status_t _cairo_hash_table_insert(cairo_hash_table_t *hash_table, cairo_hash_entry_t *entry)
Definition: cairo-hash.c:455
void _cairo_hash_table_remove(cairo_hash_table_t *hash_table, cairo_hash_entry_t *key)
Definition: cairo-hash.c:520
void _cairo_hash_table_destroy(cairo_hash_table_t *hash_table)
Definition: cairo-hash.c:214
cairo_hash_table_t * _cairo_hash_table_create(cairo_hash_keys_equal_func_t keys_equal)
Definition: cairo-hash.c:163
void * _cairo_hash_table_lookup(cairo_hash_table_t *hash_table, cairo_hash_entry_t *key)
Definition: cairo-hash.c:338
cairo_surface_t * cairo_image_surface_create(cairo_format_t format, int width, int height)
#define _cairo_malloc_ab(a, size)
#define _cairo_malloc(size)
cairo_status_t cairo_matrix_invert(cairo_matrix_t *matrix)
Definition: cairo-matrix.c:586
void cairo_matrix_transform_distance(const cairo_matrix_t *matrix, double *dx, double *dy)
Definition: cairo-matrix.c:387
void cairo_matrix_init(cairo_matrix_t *matrix, double xx, double yx, double xy, double yy, double x0, double y0)
Definition: cairo-matrix.c:111
void cairo_matrix_init_identity(cairo_matrix_t *matrix)
Definition: cairo-matrix.c:81
void cairo_matrix_transform_point(const cairo_matrix_t *matrix, double *x, double *y)
Definition: cairo-matrix.c:410
cairo_status_t _cairo_matrix_compute_basis_scale_factors(const cairo_matrix_t *matrix, double *basis_scale, double *normal_scale, cairo_bool_t x_basis)
Definition: cairo-matrix.c:674
void cairo_matrix_scale(cairo_matrix_t *matrix, double sx, double sy)
Definition: cairo-matrix.c:242
void cairo_matrix_multiply(cairo_matrix_t *result, const cairo_matrix_t *a, const cairo_matrix_t *b)
Definition: cairo-matrix.c:331
#define CAIRO_MUTEX_UNLOCK
#define CAIRO_MUTEX_LOCK
cairo_status_t _cairo_path_fixed_curve_to(cairo_path_fixed_t *path, cairo_fixed_t x0, cairo_fixed_t y0, cairo_fixed_t x1, cairo_fixed_t y1, cairo_fixed_t x2, cairo_fixed_t y2)
cairo_status_t _cairo_path_fixed_move_to(cairo_path_fixed_t *path, cairo_fixed_t x, cairo_fixed_t y)
cairo_status_t _cairo_path_fixed_line_to(cairo_path_fixed_t *path, cairo_fixed_t x, cairo_fixed_t y)
cairo_path_fixed_t * _cairo_path_fixed_create(void)
cairo_status_t _cairo_path_fixed_close_path(cairo_path_fixed_t *path)
cairo_bool_t _cairo_path_fixed_get_current_point(cairo_path_fixed_t *path, cairo_fixed_t *x, cairo_fixed_t *y)
void _cairo_path_fixed_destroy(cairo_path_fixed_t *path)
const cairo_solid_pattern_t _cairo_pattern_white
#define _cairo_reference_count_dec_and_test(RC)
cairo_int_status_t _cairo_truetype_get_style(cairo_scaled_font_t *scaled_font, int *weight, cairo_bool_t *bold, cairo_bool_t *italic)
cairo_status_t _cairo_scaled_font_init(cairo_scaled_font_t *scaled_font, cairo_font_face_t *font_face, const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, const cairo_font_options_t *options, const cairo_scaled_font_backend_t *backend)
void _cairo_scaled_font_thaw_cache(cairo_scaled_font_t *scaled_font)
void _cairo_scaled_glyph_set_surface(cairo_scaled_glyph_t *scaled_glyph, cairo_scaled_font_t *scaled_font, cairo_image_surface_t *surface)
void cairo_scaled_font_extents(cairo_scaled_font_t *scaled_font, cairo_font_extents_t *extents)
void _cairo_scaled_font_freeze_cache(cairo_scaled_font_t *scaled_font)
cairo_int_status_t _cairo_scaled_glyph_lookup(cairo_scaled_font_t *scaled_font, unsigned long index, cairo_scaled_glyph_info_t info, cairo_scaled_glyph_t **scaled_glyph_ret)
void _cairo_scaled_glyph_set_metrics(cairo_scaled_glyph_t *scaled_glyph, cairo_scaled_font_t *scaled_font, cairo_text_extents_t *fs_metrics)
void _cairo_scaled_glyph_set_path(cairo_scaled_glyph_t *scaled_glyph, cairo_scaled_font_t *scaled_font, cairo_path_fixed_t *path)
void _cairo_scaled_font_fini(cairo_scaled_font_t *scaled_font)
cairo_status_t _cairo_scaled_font_set_metrics(cairo_scaled_font_t *scaled_font, cairo_font_extents_t *fs_metrics)
void cairo_surface_destroy(cairo_surface_t *surface)
void cairo_surface_set_device_offset(cairo_surface_t *surface, double x_offset, double y_offset)
cairo_status_t _cairo_surface_paint(cairo_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_clip_t *clip)
void cairo_surface_unmap_image(cairo_surface_t *surface, cairo_surface_t *image)
cairo_surface_t * cairo_surface_map_to_image(cairo_surface_t *surface, const cairo_rectangle_int_t *extents)
cairo_status_t _cairo_utf8_to_utf16(const char *str, int len, uint16_t **result, int *items_written)
cairo_surface_t * cairo_win32_surface_create_with_dib(cairo_format_t format, int width, int height)
@ CAIRO_FONT_SLANT_ITALIC
Definition: cairo.h:1265
@ CAIRO_FONT_SLANT_OBLIQUE
Definition: cairo.h:1266
@ CAIRO_FONT_SLANT_NORMAL
Definition: cairo.h:1264
int cairo_bool_t
Definition: cairo.h:107
@ CAIRO_STATUS_SUCCESS
Definition: cairo.h:315
@ CAIRO_STATUS_NO_MEMORY
Definition: cairo.h:317
@ CAIRO_STATUS_FONT_TYPE_MISMATCH
Definition: cairo.h:341
@ CAIRO_HINT_METRICS_OFF
Definition: cairo.h:1359
@ CAIRO_ANTIALIAS_SUBPIXEL
Definition: cairo.h:715
@ CAIRO_ANTIALIAS_DEFAULT
Definition: cairo.h:710
@ CAIRO_ANTIALIAS_BEST
Definition: cairo.h:720
@ CAIRO_ANTIALIAS_GOOD
Definition: cairo.h:719
@ CAIRO_ANTIALIAS_FAST
Definition: cairo.h:718
@ CAIRO_ANTIALIAS_NONE
Definition: cairo.h:713
@ CAIRO_ANTIALIAS_GRAY
Definition: cairo.h:714
@ CAIRO_OPERATOR_SOURCE
Definition: cairo.h:616
enum _cairo_status cairo_status_t
@ CAIRO_FONT_TYPE_WIN32
Definition: cairo.h:1575
@ CAIRO_FORMAT_A8
Definition: cairo.h:420
@ CAIRO_FORMAT_RGB24
Definition: cairo.h:419
@ CAIRO_FORMAT_ARGB32
Definition: cairo.h:418
@ CAIRO_HINT_STYLE_NONE
Definition: cairo.h:1336
@ CAIRO_FONT_WEIGHT_BOLD
Definition: cairo.h:1280
@ CAIRO_FONT_WEIGHT_NORMAL
Definition: cairo.h:1279
enum _cairo_scaled_glyph_info cairo_scaled_glyph_info_t
#define ASSERT_NOT_REACHED
Definition: cairoint.h:155
static int _cairo_lround(double r)
Definition: cairoint.h:767
@ CAIRO_SCALED_GLYPH_INFO_PATH
Definition: cairoint.h:485
@ CAIRO_SCALED_GLYPH_INFO_SURFACE
Definition: cairoint.h:484
@ CAIRO_SCALED_GLYPH_INFO_METRICS
Definition: cairoint.h:483
#define _CAIRO_HASH_INIT_VALUE
Definition: cairoint.h:421
#define _cairo_scaled_glyph_index(g)
Definition: cairoint.h:431
void cairo_win32_scaled_font_get_logical_to_device(cairo_scaled_font_t *scaled_font, cairo_matrix_t *logical_to_device)
cairo_font_face_t * cairo_win32_font_face_create_for_hfont(HFONT font)
cairo_font_face_t * cairo_win32_font_face_create_for_logfontw_hfont(LOGFONTW *logfont, HFONT font)
const cairo_scaled_font_backend_t _cairo_win32_scaled_font_backend
void cairo_win32_scaled_font_get_device_to_logical(cairo_scaled_font_t *scaled_font, cairo_matrix_t *device_to_logical)
cairo_bool_t _cairo_win32_scaled_font_is_type1(cairo_scaled_font_t *scaled_font)
double cairo_win32_scaled_font_get_metrics_factor(cairo_scaled_font_t *scaled_font)
void _cairo_win32_font_reset_static_data(void)
cairo_bool_t _cairo_win32_scaled_font_is_bitmap(cairo_scaled_font_t *scaled_font)
cairo_font_face_t * cairo_win32_font_face_create_for_logfontw(LOGFONTW *logfont)
const cairo_font_face_backend_t _cairo_win32_font_face_backend
cairo_status_t cairo_win32_scaled_font_select_font(cairo_scaled_font_t *scaled_font, HDC hdc)
void cairo_win32_scaled_font_done_font(cairo_scaled_font_t *scaled_font)
#define WIN32_FONT_LOGICAL_SCALE
cairo_status_t _cairo_win32_print_gdi_error(const char *context)
#define to_win32_surface(S)
static void _cairo_matrix_to_win32_xform(const cairo_matrix_t *m, XFORM *xform)
static cairo_bool_t _have_cleartype_quality(void)
static cairo_hash_table_t * cairo_win32_font_face_hash_table
static cairo_int_status_t _cairo_win32_scaled_font_load_type1_data(void *abstract_font, long offset, unsigned char *buffer, unsigned long *length)
static cairo_int_status_t _cairo_win32_scaled_font_index_to_ucs4(void *abstract_font, unsigned long index, uint32_t *ucs4)
static cairo_status_t _cairo_win32_scaled_font_set_metrics(cairo_win32_scaled_font_t *scaled_font)
static cairo_hash_table_t * _cairo_win32_font_face_hash_table_lock(void)
static cairo_status_t _cairo_win32_scaled_font_init_glyph_metrics(cairo_win32_scaled_font_t *scaled_font, cairo_scaled_glyph_t *scaled_glyph)
static cairo_status_t _win32_scaled_font_set_world_transform(cairo_win32_scaled_font_t *scaled_font, HDC hdc)
static cairo_status_t _cairo_win32_font_face_scaled_font_create(void *abstract_face, const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, const cairo_font_options_t *options, cairo_scaled_font_t **font)
static cairo_bool_t _cairo_scaled_font_is_win32(cairo_scaled_font_t *scaled_font)
static cairo_status_t _finish_glyphs(cairo_glyph_state_t *state)
static void _start_glyphs(cairo_glyph_state_t *state, cairo_win32_scaled_font_t *scaled_font, HDC hdc)
static cairo_int_status_t _cairo_win32_scaled_font_is_synthetic(void *abstract_font, cairo_bool_t *is_synthetic)
static cairo_int_status_t _cairo_win32_scaled_font_load_truetype_table(void *abstract_font, unsigned long tag, long offset, unsigned char *buffer, unsigned long *length)
static int _cairo_win32_font_face_keys_equal(const void *key_a, const void *key_b)
static void _cairo_win32_scaled_font_fini(void *abstract_font)
static cairo_status_t _cairo_win32_font_face_create_for_toy(cairo_toy_font_face_t *toy_face, cairo_font_face_t **font_face)
static cairo_status_t _win32_scaled_font_create(LOGFONTW *logfont, HFONT face_hfont, cairo_font_face_t *font_face, const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, const cairo_font_options_t *options, cairo_scaled_font_t **font_out)
static cairo_status_t _win32_scaled_font_get_scaled_hfont(cairo_win32_scaled_font_t *scaled_font, HFONT *hfont_out)
#define TT_PRIM_CSPLINE
static cairo_int_status_t _cairo_win32_scaled_font_glyph_init(void *abstract_font, cairo_scaled_glyph_t *scaled_glyph, cairo_scaled_glyph_info_t info)
static cairo_status_t _win32_scaled_font_set_identity_transform(HDC hdc)
static cairo_status_t _compute_transform(cairo_win32_scaled_font_t *scaled_font, cairo_matrix_t *sc)
static unsigned long _cairo_win32_scaled_font_ucs4_to_index(void *abstract_font, uint32_t ucs4)
static void _cairo_win32_font_face_init_key(cairo_win32_font_face_t *key, LOGFONTW *logfont, HFONT font)
static void _cairo_win32_scaled_font_done_unscaled_font(cairo_scaled_font_t *scaled_font)
static cairo_bool_t _cairo_win32_font_face_destroy(void *abstract_face)
static HDC _get_global_font_dc(void)
static cairo_status_t _flush_glyphs(cairo_glyph_state_t *state)
static cairo_status_t _cairo_win32_scaled_font_select_unscaled_font(cairo_scaled_font_t *scaled_font, HDC hdc)
static void _cairo_win32_transform_FIXED_to_fixed(cairo_matrix_t *matrix, FIXED Fx, FIXED Fy, cairo_fixed_t *fx, cairo_fixed_t *fy)
#define FE_FONTSMOOTHINGCLEARTYPE
#define CMAP_TAG
#define NEARLY_ZERO(d)
static cairo_int_status_t _cairo_win32_scaled_font_index_to_glyph_name(void *abstract_font, char **glyph_names, int num_glyph_names, unsigned long glyph_index, unsigned long *glyph_array_index)
static cairo_int_status_t _cairo_win32_scaled_font_text_to_glyphs(void *abstract_font, double x, double y, const char *utf8, cairo_glyph_t **glyphs, int *num_glyphs)
static cairo_surface_t * _compute_mask(cairo_surface_t *surface, int quality)
static cairo_status_t _cairo_win32_scaled_font_init_glyph_path(cairo_win32_scaled_font_t *scaled_font, cairo_scaled_glyph_t *scaled_glyph)
static BYTE _get_system_quality(void)
static cairo_bool_t _is_scale(const cairo_matrix_t *matrix, double scale)
#define CLEARTYPE_QUALITY
static cairo_status_t _cairo_win32_scaled_font_init_glyph_surface(cairo_win32_scaled_font_t *scaled_font, cairo_scaled_glyph_t *scaled_glyph)
#define SPI_GETFONTSMOOTHINGTYPE
static cairo_status_t _draw_glyphs_on_surface(cairo_win32_surface_t *surface, cairo_win32_scaled_font_t *scaled_font, COLORREF color, int x_offset, int y_offset, const cairo_glyph_t *glyphs, int num_glyphs)
static void _cairo_win32_font_face_hash_table_destroy(void)
static cairo_status_t _win32_scaled_font_get_unscaled_hfont(cairo_win32_scaled_font_t *scaled_font, HDC hdc, HFONT *hfont_out)
static void _cairo_win32_font_face_hash_table_unlock(void)
static cairo_status_t _add_glyph(cairo_glyph_state_t *state, unsigned long index, double device_x, double device_y)
static cairo_int_status_t _cairo_win32_scaled_font_type1_text_to_glyphs(cairo_win32_scaled_font_t *scaled_font, double x, double y, const char *utf8, cairo_glyph_t **glyphs, int *num_glyphs)
BOOL
Definition: dd.h:100
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
#define free(a)
Definition: decNumber.cpp:310
void glyphs(int opcode)
Definition: disdvi.c:775
int strcmp()
Definition: coll.cpp:143
#define info
Definition: dviinfo.c:42
static gregorio_element ** elements
mpz_t * f
Definition: gen-fib.c:34
int base
Definition: gsftopk.c:1502
#define memcpy(d, s, n)
Definition: gsftopk.c:64
int unicode
Definition: hbf2gf.c:267
double y_scale
Definition: hbf2gf.c:275
assert(pcxLoadImage24((char *)((void *) 0), fp, pinfo, hdr))
unsigned char * image
Definition: in_pcx.cpp:323
#define likely(x)
Definition: jbig2arith.cc:115
#define unlikely(x)
Definition: jbig2arith.cc:116
#define MAX(a, b)
Definition: jpegint.h:267
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
sizeof(AF_ModuleRec)
kerning y
Definition: ttdriver.c:212
int int double double double char double points
Definition: gdfx.h:18
int int cy
Definition: gdfx.h:13
int cx
Definition: gdfx.h:12
unsigned short uint16_t
Definition: stdint.h:79
unsigned int uint32_t
Definition: stdint.h:80
unsigned char uint8_t
Definition: stdint.h:78
unsigned char BYTE
Definition: sfnt.h:34
#define INT_MAX
Definition: c-minmax.h:53
static int ret
Definition: convert.c:72
#define transform(xusr, yusr, xdev, ydev)
Definition: type1.c:1420
#define length(c)
Definition: ctangleboot.c:65
unsigned short WORD
Definition: common.h:143
unsigned int UINT
Definition: common.h:145
int INT
Definition: common.h:144
#define x_offset
Definition: mfluac.c:342
#define y_offset
Definition: mfluac.c:343
#define RGB
Definition: mitsu.h:92
unsigned int DWORD
Definition: mktexlib.h:49
float x
Definition: cordic.py:15
utf< uint8 > utf8
Definition: UtfCodec.h:249
utf< uint16 > utf16
Definition: UtfCodec.h:248
static HDC hdc
static cairo_surface_t * surface
Definition: pdftocairo.cc:234
float ** matrix()
#define res(length)
Definition: picttoppm.c:287
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
#define index(s, c)
Definition: plain2.h:351
double scale
Definition: pnmhistmap.c:38
static int offset
Definition: ppmtogif.c:642
static int quality
Definition: ppmtopjxl.c:45
bstring c int memset(void *s, int c, int length)
#define x1
#define y1
#define y2
#define x2
#define status
#define glyph_index()
struct hash_table hash_table
#define mask(n)
Definition: lbitlib.c:93
static int32 buffer_size
Definition: rate.c:83
#define uint32_t
Definition: stdint.in.h:168
cairo_antialias_t antialias
cairo_hint_style_t hint_style
cairo_hint_metrics_t hint_metrics
cairo_point_t p2
cairo_point_t p1
double yy
Definition: cairo.h:194
cairo_font_options_t options
const cairo_scaled_font_backend_t * backend
const char * family
Definition: cairoint.h:474
cairo_font_slant_t slant
Definition: cairoint.h:476
cairo_font_weight_t weight
Definition: cairoint.h:477
cairo_font_face_t base
Definition: nsfix.c:44
Definition: utils.c:300
cairo_matrix_t device_to_logical
cairo_matrix_t logical_to_device
cairo_scaled_font_t base
Definition: pdfdev.c:706
Definition: mpost.c:242
Definition: pbmfont.h:11
Definition: drvpic.cpp:36
Definition: pbmfont.h:4
int width
Definition: pbmfont.h:5
int x
Definition: pbmfont.h:6
int height
Definition: pbmfont.h:5
int y
Definition: pbmfont.h:6
Definition: sd.h:76
Definition: mendex.h:20
Definition: tpic.c:45
Definition: sh2.c:920
Definition: xmlparse.c:179
pointer path
Definition: t1imager.h:36
int j
Definition: t4ht.c:1589
#define key
Definition: tex2xindy.c:753
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
TT_Glyph glyph
Definition: ttf2pfb.c:162
#define FAIL(ec)
#define is_type1(fm)
Definition: ptexmac.h:182
#define buffer
Definition: xmlparse.c:611