1 | /* viewer-pangoft2.c: PangoFT2 viewer backend. |
2 | * |
3 | * Copyright (C) 1999,2004,2005 Red Hat, Inc. |
4 | * Copyright (C) 2001 Sun Microsystems |
5 | * |
6 | * This library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Library General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Library General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this library; if not, write to the |
18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
19 | * Boston, MA 02111-1307, USA. |
20 | */ |
21 | |
22 | #include "config.h" |
23 | #include <errno.h> |
24 | #include <stdlib.h> |
25 | #include <stdio.h> |
26 | #include <string.h> |
27 | |
28 | #include "viewer-render.h" |
29 | #include "viewer.h" |
30 | |
31 | #include <pango/pangoft2.h> |
32 | |
33 | static void |
34 | substitute_func (FcPattern *pattern, |
35 | gpointer data G_GNUC_UNUSED) |
36 | { |
37 | if (opt_antialias != ANTIALIAS_DEFAULT) |
38 | { |
39 | FcPatternDel (p: pattern, FC_ANTIALIAS); |
40 | FcPatternAddBool (p: pattern, FC_ANTIALIAS, b: opt_antialias != ANTIALIAS_NONE); |
41 | } |
42 | if (opt_hinting != HINT_DEFAULT) |
43 | { |
44 | FcPatternDel (p: pattern, FC_HINTING); |
45 | FcPatternAddBool (p: pattern, FC_HINTING, b: opt_hinting != HINT_NONE); |
46 | |
47 | FcPatternDel (p: pattern, FC_AUTOHINT); |
48 | FcPatternAddBool (p: pattern, FC_AUTOHINT, b: opt_hinting == HINT_AUTO); |
49 | } |
50 | } |
51 | |
52 | static gpointer |
53 | pangoft2_view_create (const PangoViewer *klass G_GNUC_UNUSED) |
54 | { |
55 | PangoFontMap *fontmap; |
56 | fontmap = pango_ft2_font_map_new (); |
57 | |
58 | pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (fontmap), dpi_x: opt_dpi, dpi_y: opt_dpi); |
59 | pango_fc_font_map_set_default_substitute (PANGO_FC_FONT_MAP (fontmap), func: substitute_func, NULL, NULL); |
60 | |
61 | return fontmap; |
62 | } |
63 | |
64 | static void |
65 | pangoft2_view_destroy (gpointer instance) |
66 | { |
67 | g_object_unref (object: instance); |
68 | } |
69 | |
70 | static PangoContext * |
71 | pangoft2_view_get_context (gpointer instance) |
72 | { |
73 | return pango_font_map_create_context (PANGO_FONT_MAP (instance)); |
74 | } |
75 | |
76 | static gpointer |
77 | pangoft2_view_create_surface (gpointer instance G_GNUC_UNUSED, |
78 | int width, |
79 | int height) |
80 | { |
81 | FT_Bitmap *bitmap; |
82 | |
83 | bitmap = g_slice_new (FT_Bitmap); |
84 | bitmap->width = width; |
85 | bitmap->pitch = (bitmap->width + 3) & ~3; |
86 | bitmap->rows = height; |
87 | bitmap->buffer = g_malloc (n_bytes: bitmap->pitch * bitmap->rows); |
88 | bitmap->num_grays = 256; |
89 | bitmap->pixel_mode = ft_pixel_mode_grays; |
90 | memset (s: bitmap->buffer, c: 0x00, n: bitmap->pitch * bitmap->rows); |
91 | |
92 | return bitmap; |
93 | } |
94 | |
95 | static void |
96 | pangoft2_view_destroy_surface (gpointer instance G_GNUC_UNUSED, |
97 | gpointer surface) |
98 | { |
99 | FT_Bitmap *bitmap = (FT_Bitmap *) surface; |
100 | |
101 | g_free (mem: bitmap->buffer); |
102 | g_slice_free (FT_Bitmap, bitmap); |
103 | } |
104 | |
105 | static void |
106 | render_callback (PangoLayout *layout, |
107 | int x, |
108 | int y, |
109 | gpointer context, |
110 | gpointer state G_GNUC_UNUSED) |
111 | { |
112 | pango_ft2_render_layout (bitmap: (FT_Bitmap *)context, |
113 | layout, |
114 | x, y); |
115 | } |
116 | |
117 | static void |
118 | pangoft2_view_render (gpointer instance G_GNUC_UNUSED, |
119 | gpointer surface, |
120 | PangoContext *context, |
121 | int *width, |
122 | int *height, |
123 | gpointer state) |
124 | { |
125 | int pix_idx; |
126 | FT_Bitmap *bitmap = (FT_Bitmap *) surface; |
127 | |
128 | do_output (context, render_cb: render_callback, NULL, cb_context: surface, cb_data: state, width, height); |
129 | |
130 | for (pix_idx=0; pix_idx<bitmap->pitch * bitmap->rows; pix_idx++) |
131 | bitmap->buffer[pix_idx] = 255 - bitmap->buffer[pix_idx]; |
132 | } |
133 | |
134 | static void |
135 | pangoft2_view_write (gpointer instance G_GNUC_UNUSED, |
136 | gpointer surface, |
137 | FILE *stream, |
138 | int width, |
139 | int height) |
140 | { |
141 | int row; |
142 | FT_Bitmap *bitmap = (FT_Bitmap *) surface; |
143 | |
144 | /* Write it as pgm to output */ |
145 | fprintf(stream: stream, |
146 | format: "P5\n" |
147 | "%d %d\n" |
148 | "255\n" , width, height); |
149 | for (row = 0; row < height; row++) |
150 | fwrite (ptr: bitmap->buffer + row * bitmap->pitch, size: 1, n: width, s: stream); |
151 | } |
152 | |
153 | const PangoViewer pangoft2_viewer = { |
154 | "PangoFT2" , |
155 | "ft2" , |
156 | ".pgm" , |
157 | pangoft2_view_create, |
158 | pangoft2_view_destroy, |
159 | pangoft2_view_get_context, |
160 | pangoft2_view_create_surface, |
161 | pangoft2_view_destroy_surface, |
162 | pangoft2_view_render, |
163 | pangoft2_view_write, |
164 | NULL, |
165 | NULL, |
166 | NULL |
167 | }; |
168 | |