NetSurf
font.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2008 François Revol <mmu_man@users.sourceforge.net>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/** \file
20 * Font handling (BeOS implementation).
21 * TODO: check for correctness, the code is taken from the GTK one.
22 * maybe use the current view instead of constructing a new BFont each time ?
23 */
24
25
26#define __STDBOOL_H__ 1
27#include <stdbool.h>
28#include <assert.h>
29#include <stdio.h>
30#include <Font.h>
31#include <String.h>
32#include <View.h>
33
34extern "C" {
35#include "utils/utils.h"
36#include "utils/log.h"
37#include "utils/nsoption.h"
38#include "utils/nsurl.h"
39#include "netsurf/layout.h"
40}
41
42#include "beos/gui.h"
43#include "beos/font.h"
44#include "beos/plotters.h"
45
46
47/**
48 * Convert a font style to a PangoFontDescription.
49 *
50 * \param font Beos font object.
51 * \param fstyle style for this text
52 */
53void nsbeos_style_to_font(BFont &font, const struct plot_font_style *fstyle)
54{
55 float size;
56 uint16 face = 0;
57 const char *family;
58
59 switch (fstyle->family) {
61 family = nsoption_charp(font_serif);
62 break;
64 family = nsoption_charp(font_mono);
65 break;
67 family = nsoption_charp(font_cursive);
68 break;
70 family = nsoption_charp(font_fantasy);
71 break;
73 default:
74 family = nsoption_charp(font_sans);
75 break;
76 }
77
78 if ((fstyle->flags & FONTF_ITALIC)) {
79 face = B_ITALIC_FACE;
80 } else if ((fstyle->flags & FONTF_OBLIQUE)) {
81 face = B_ITALIC_FACE;
82 // XXX: no OBLIQUE flag ??
83 // maybe find "Oblique" style
84 // or use SetShear() ?
85 }
86
87#ifndef __HAIKU__XXX
88 if (fstyle->weight >= 600) {
89 face |= B_BOLD_FACE;
90 }
91#else
92 if (fstyle->weight >= 600) {
93 if (fstyle->weight >= 800)
94 face |= B_HEAVY_FACE;
95 else
96 face |= B_BOLD_FACE;
97 } else if (fstyle->weight <= 300) {
98 face |= B_LIGHT_FACE;
99 }
100#endif
101/*
102 case CSS_FONT_WEIGHT_100: weight = 100; break;
103 case CSS_FONT_WEIGHT_200: weight = 200; break;
104 case CSS_FONT_WEIGHT_300: weight = 300; break;
105 case CSS_FONT_WEIGHT_400: weight = 400; break;
106 case CSS_FONT_WEIGHT_500: weight = 500; break;
107 case CSS_FONT_WEIGHT_600: weight = 600; break;
108 case CSS_FONT_WEIGHT_700: weight = 700; break;
109 case CSS_FONT_WEIGHT_800: weight = 800; break;
110 case CSS_FONT_WEIGHT_900: weight = 900; break;
111*/
112
113 if (!face)
114 face = B_REGULAR_FACE;
115
116//fprintf(stderr, "nsbeos_style_to_font: %d, %d, %d -> '%s' %04x\n", style->font_family, style->font_style, style->font_weight, family, face);
117
118 if (family) {
119 font_family beos_family;
120
121 strncpy(beos_family, family, B_FONT_FAMILY_LENGTH);
122 // Ensure it's terminated
123 beos_family[B_FONT_FAMILY_LENGTH] = '\0';
124
125 font.SetFamilyAndFace(beos_family, face);
126 } else {
127 //XXX not used
128 font = be_plain_font;
129 font.SetFace(face);
130 }
131
132//fprintf(stderr, "nsbeos_style_to_font: value %f unit %d\n", style->font_size.value.length.value, style->font_size.value.length.unit);
133 size = fstyle->size / PLOT_STYLE_SCALE;
134
135//fprintf(stderr, "nsbeos_style_to_font: %f %d\n", size, style->font_size.value.length.unit);
136
137 font.SetSize(size);
138}
139
140
141/**
142 * Measure the width of a string.
143 *
144 * \param fstyle style for this text
145 * \param string UTF-8 string to measure
146 * \param length length of string
147 * \param width updated to width of string[0..length)
148 * \return true on success, false on error and error reported
149 */
151 const char *string, size_t length,
152 int *width)
153{
154 //fprintf(stderr, "%s(, '%s', %d, )\n", __FUNCTION__, string, length);
155 BFont font;
156
157 if (length == 0) {
158 *width = 0;
159 return NSERROR_OK;
160 }
161
162 nsbeos_style_to_font(font, fstyle);
163 *width = (int)font.StringWidth(string, length);
164
165 return NSERROR_OK;
166}
167
168
169static int utf8_char_len(const char *c)
170{
171 uint8 *p = (uint8 *)c;
172 uint8 m = 0xE0;
173 uint8 v = 0xC0;
174 int i;
175
176 if (!*p)
177 return 0;
178 if ((*p & 0x80) == 0)
179 return 1;
180 if ((*p & 0xC0) == 0x80)
181 return 1; // actually one of the remaining bytes...
182 for (i = 2; i < 5; i++) {
183 if ((*p & m) == v)
184 return i;
185 v = (v >> 1) | 0x80;
186 m = (m >> 1) | 0x80;
187 }
188 return i;
189}
190
191
192/**
193 * Find the position in a string where an x coordinate falls.
194 *
195 * \param fstyle style for this text
196 * \param string UTF-8 string to measure
197 * \param length length of string
198 * \param x x coordinate to search for
199 * \param char_offset updated to offset in string of actual_x, [0..length]
200 * \param actual_x updated to x coordinate of character closest to x
201 * \return true on success, false on error and error reported
202 */
204 const char *string, size_t length,
205 int x, size_t *char_offset, int *actual_x)
206{
207 NSLOG(netsurf, DEEPDEBUG, "(, '%s', %d, %d, , )", string, length, x);
208
209 int index;
210 BFont font;
211
212 nsbeos_style_to_font(font, fstyle);
213 BString str(string);
214 int32 len = str.CountChars();
215 float escapements[len];
216 float esc = 0.0;
217 float current = 0.0;
218 int i;
219
220 index = 0;
221 font.GetEscapements(string, len, escapements);
222 // slow but it should work
223 for (i = 0; string[index] && i < len; i++) {
224 esc += escapements[i];
225 current = font.Size() * esc;
226 index += utf8_char_len(&string[index]);
227 // is current char already too far away?
228 if (x < current)
229 break;
230 }
231 *actual_x = (int)current;
232 *char_offset = i; //index;
233
234 return NSERROR_OK;
235}
236
237
238/**
239 * Find where to split a string to make it fit a width.
240 *
241 * \param fstyle style for this text
242 * \param string UTF-8 string to measure
243 * \param length length of string, in bytes
244 * \param x width available
245 * \param char_offset updated to offset in string of actual_x, [1..length]
246 * \param actual_x updated to x coordinate of character closest to x
247 * \return true on success, false on error and error reported
248 *
249 * On exit, char_offset indicates first character after split point.
250 *
251 * Note: char_offset of 0 should never be returned.
252 *
253 * Returns:
254 * char_offset giving split point closest to x, where actual_x <= x
255 * else
256 * char_offset giving split point closest to x, where actual_x > x
257 *
258 * Returning char_offset == length means no split possible
259 */
261 const char *string, size_t length,
262 int x, size_t *char_offset, int *actual_x)
263{
264 NSLOG(netsurf, DEEPDEBUG, "(, '%s', %d, %d, , )", string, length, x);
265 int index = 0;
266 BFont font;
267
268 nsbeos_style_to_font(font, fstyle);
269 BString str(string);
270 int32 len = str.CountChars();
271 float escapements[len];
272 float esc = 0.0;
273 float current = 0.0;
274 float last_x = 0.0;
275 int i;
276 int last_space = 0;
277
278 font.GetEscapements(string, len, escapements);
279 // very slow but it should work
280 for (i = 0; string[index] && i < len; i++) {
281 if (string[index] == ' ') {
282 last_x = current;
283 last_space = index;
284 }
285 if (x < current && last_space != 0) {
286 *actual_x = (int)last_x;
287 *char_offset = last_space;
288 return NSERROR_OK;;
289 }
290 esc += escapements[i];
291 current = font.Size() * esc;
292 index += utf8_char_len(&string[index]);
293 }
294 *actual_x = MIN(*actual_x, (int)current);
295 *char_offset = index;
296
297 return NSERROR_OK;
298}
299
300
301/**
302 * Render a string.
303 *
304 * \param fstyle style for this text
305 * \param string UTF-8 string to measure
306 * \param length length of string
307 * \param x x coordinate
308 * \param y y coordinate
309 * \return true on success, false on error and error reported
310 */
311
313 const char *string, size_t length,
314 int x, int y)
315{
316 //fprintf(stderr, "%s(, '%s', %d, %d, %d, )\n", __FUNCTION__, string, length, x, y);
317 //CALLED();
318 BFont font;
319 rgb_color oldbg;
320 rgb_color background;
321 rgb_color foreground;
322 BView *view;
323 float size;
324
325 if (length == 0)
326 return true;
327
328 nsbeos_style_to_font(font, fstyle);
329 background = nsbeos_rgb_colour(fstyle->background);
330 foreground = nsbeos_rgb_colour(fstyle->foreground);
331
332 view = nsbeos_current_gc/*_lock*/();
333 if (view == NULL) {
334 beos_warn_user("No GC", 0);
335 return false;
336 }
337
338 oldbg = view->LowColor();
339 drawing_mode oldmode = view->DrawingMode();
340 view->SetLowColor(B_TRANSPARENT_32_BIT);
341
342 //view->SetScale() XXX
343
344//printf("nsfont_paint: Size: %f\n", font.Size());
345 size = (float)font.Size();
346#warning XXX use scale
347
348 view->SetFont(&font);
349 view->SetHighColor(foreground);
350 view->SetDrawingMode(B_OP_OVER);
351
352 BString line(string, length);
353
354 BPoint where(x, y + 1);
355 view->DrawString(line.String(), where);
356
357 view->SetDrawingMode(oldmode);
358 if (memcmp(&oldbg, &background, sizeof(rgb_color)))
359 view->SetLowColor(oldbg);
360
361 //nsbeos_current_gc_unlock();
362
363 return true;
364}
365
366
368 /*.width = */beos_font_width,
369 /*.position = */beos_font_position,
370 /*.split = */beos_font_split
371};
372
static struct s_view view
Definition: plot.c:199
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_OK
No error.
Definition: errors.h:30
static nserror beos_font_position(const plot_font_style_t *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x)
Find the position in a string where an x coordinate falls.
Definition: font.cpp:203
void nsbeos_style_to_font(BFont &font, const struct plot_font_style *fstyle)
Convert a font style to a PangoFontDescription.
Definition: font.cpp:53
static nserror beos_font_split(const plot_font_style_t *fstyle, const char *string, size_t length, int x, size_t *char_offset, int *actual_x)
Find where to split a string to make it fit a width.
Definition: font.cpp:260
static nserror beos_font_width(const plot_font_style_t *fstyle, const char *string, size_t length, int *width)
Measure the width of a string.
Definition: font.cpp:150
static int utf8_char_len(const char *c)
Definition: font.cpp:169
struct gui_layout_table * beos_layout_table
Definition: font.cpp:373
static struct gui_layout_table layout_table
Definition: font.cpp:367
bool nsfont_paint(const plot_font_style_t *fstyle, const char *string, size_t length, int x, int y)
Render a string.
Definition: font.cpp:312
Beos font layout handling interface.
Target independent plotting (BeOS interface).
nserror beos_warn_user(const char *warning, const char *detail)
Display a warning for a serious problem (eg memory exhaustion).
Definition: gui.cpp:116
Interface to platform-specific layout operation table.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
NetSurf URL handling (interface).
uint8_t uint8
Definition: os3support.h:180
#define MIN(a, b)
Definition: os3support.h:51
int32_t int32
Definition: os3support.h:183
uint16_t uint16
Definition: os3support.h:182
@ FONTF_ITALIC
Definition: plot_style.h:103
@ FONTF_OBLIQUE
Definition: plot_style.h:104
@ PLOT_FONT_FAMILY_CURSIVE
Definition: plot_style.h:92
@ PLOT_FONT_FAMILY_SANS_SERIF
Definition: plot_style.h:89
@ PLOT_FONT_FAMILY_FANTASY
Definition: plot_style.h:93
@ PLOT_FONT_FAMILY_MONOSPACE
Definition: plot_style.h:91
@ PLOT_FONT_FAMILY_SERIF
Definition: plot_style.h:90
#define PLOT_STYLE_SCALE
Scaling factor for plot styles.
Definition: plot_style.h:45
rgb_color nsbeos_rgb_colour(colour c)
Definition: plotters.cpp:169
BView * nsbeos_current_gc(void)
Definition: plotters.cpp:70
int width
Definition: gui.c:159
Font style for plotting.
Definition: plot_style.h:111
plot_font_generic_family_t family
Generic family to plot with.
Definition: plot_style.h:118
colour foreground
Colour of text.
Definition: plot_style.h:123
plot_font_flags_t flags
Font flags.
Definition: plot_style.h:121
plot_style_fixed size
Font size, in pt.
Definition: plot_style.h:119
colour background
Background colour to blend to, if appropriate.
Definition: plot_style.h:122
int weight
Font weight: value in range [100,900] as per CSS.
Definition: plot_style.h:120
Option reading and saving interface.
#define nsoption_charp(OPTION)
Get the value of a string option.
Definition: nsoption.h:297
Interface to a number of general purpose functionality.
static nserror line(const struct redraw_context *ctx, const plot_style_t *style, const struct rect *line)
Plots a line.
Definition: plot.c:579