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/inttypes.h"
40#include "netsurf/layout.h"
41}
42
43#include "beos/gui.h"
44#include "beos/font.h"
45#include "beos/plotters.h"
46
47
48/**
49 * Convert a font style to a PangoFontDescription.
50 *
51 * \param font Beos font object.
52 * \param fstyle style for this text
53 */
54void nsbeos_style_to_font(BFont &font, const struct plot_font_style *fstyle)
55{
56 float size;
57 uint16 face = 0;
58 const char *family;
59
60 switch (fstyle->family) {
62 family = nsoption_charp(font_serif);
63 break;
65 family = nsoption_charp(font_mono);
66 break;
68 family = nsoption_charp(font_cursive);
69 break;
71 family = nsoption_charp(font_fantasy);
72 break;
74 default:
75 family = nsoption_charp(font_sans);
76 break;
77 }
78
79 if ((fstyle->flags & FONTF_ITALIC)) {
80 face = B_ITALIC_FACE;
81 } else if ((fstyle->flags & FONTF_OBLIQUE)) {
82 face = B_ITALIC_FACE;
83 // XXX: no OBLIQUE flag ??
84 // maybe find "Oblique" style
85 // or use SetShear() ?
86 }
87
88#ifndef __HAIKU__XXX
89 if (fstyle->weight >= 600) {
90 face |= B_BOLD_FACE;
91 }
92#else
93 if (fstyle->weight >= 600) {
94 if (fstyle->weight >= 800)
95 face |= B_HEAVY_FACE;
96 else
97 face |= B_BOLD_FACE;
98 } else if (fstyle->weight <= 300) {
99 face |= B_LIGHT_FACE;
100 }
101#endif
102/*
103 case CSS_FONT_WEIGHT_100: weight = 100; break;
104 case CSS_FONT_WEIGHT_200: weight = 200; break;
105 case CSS_FONT_WEIGHT_300: weight = 300; break;
106 case CSS_FONT_WEIGHT_400: weight = 400; break;
107 case CSS_FONT_WEIGHT_500: weight = 500; break;
108 case CSS_FONT_WEIGHT_600: weight = 600; break;
109 case CSS_FONT_WEIGHT_700: weight = 700; break;
110 case CSS_FONT_WEIGHT_800: weight = 800; break;
111 case CSS_FONT_WEIGHT_900: weight = 900; break;
112*/
113
114 if (!face)
115 face = B_REGULAR_FACE;
116
117//fprintf(stderr, "nsbeos_style_to_font: %d, %d, %d -> '%s' %04x\n", style->font_family, style->font_style, style->font_weight, family, face);
118
119 if (family) {
120 font_family beos_family;
121
122 strncpy(beos_family, family, B_FONT_FAMILY_LENGTH);
123 // Ensure it's terminated
124 beos_family[B_FONT_FAMILY_LENGTH] = '\0';
125
126 font.SetFamilyAndFace(beos_family, face);
127 } else {
128 //XXX not used
129 font = be_plain_font;
130 font.SetFace(face);
131 }
132
133//fprintf(stderr, "nsbeos_style_to_font: value %f unit %d\n", style->font_size.value.length.value, style->font_size.value.length.unit);
134 size = fstyle->size / PLOT_STYLE_SCALE;
135
136//fprintf(stderr, "nsbeos_style_to_font: %f %d\n", size, style->font_size.value.length.unit);
137
138 font.SetSize(size);
139}
140
141
142/**
143 * Measure the width of a string.
144 *
145 * \param fstyle style for this text
146 * \param string UTF-8 string to measure
147 * \param length length of string
148 * \param width updated to width of string[0..length)
149 * \return true on success, false on error and error reported
150 */
152 const char *string, size_t length,
153 int *width)
154{
155 //fprintf(stderr, "%s(, '%s', %d, )\n", __FUNCTION__, string, length);
156 BFont font;
157
158 if (length == 0) {
159 *width = 0;
160 return NSERROR_OK;
161 }
162
163 nsbeos_style_to_font(font, fstyle);
164 *width = (int)font.StringWidth(string, length);
165
166 return NSERROR_OK;
167}
168
169
170static int utf8_char_len(const char *c)
171{
172 uint8 *p = (uint8 *)c;
173 uint8 m = 0xE0;
174 uint8 v = 0xC0;
175 int i;
176
177 if (!*p)
178 return 0;
179 if ((*p & 0x80) == 0)
180 return 1;
181 if ((*p & 0xC0) == 0x80)
182 return 1; // actually one of the remaining bytes...
183 for (i = 2; i < 5; i++) {
184 if ((*p & m) == v)
185 return i;
186 v = (v >> 1) | 0x80;
187 m = (m >> 1) | 0x80;
188 }
189 return i;
190}
191
192
193/**
194 * Find the position in a string where an x coordinate falls.
195 *
196 * \param fstyle style for this text
197 * \param string UTF-8 string to measure
198 * \param length length of string
199 * \param x x coordinate to search for
200 * \param char_offset updated to offset in string of actual_x, [0..length]
201 * \param actual_x updated to x coordinate of character closest to x
202 * \return true on success, false on error and error reported
203 */
205 const char *string, size_t length,
206 int x, size_t *char_offset, int *actual_x)
207{
208 NSLOG(netsurf, DEEPDEBUG, "(, '%s', %" PRIsizet ", %d, , )",
209 string, length, x);
210
211 int index;
212 BFont font;
213
214 nsbeos_style_to_font(font, fstyle);
215 BString str(string);
216 int32 len = str.CountChars();
217 float escapements[len];
218 float esc = 0.0;
219 float current = 0.0;
220 int i;
221
222 index = 0;
223 font.GetEscapements(string, len, escapements);
224 // slow but it should work
225 for (i = 0; string[index] && i < len; i++) {
226 esc += escapements[i];
227 current = font.Size() * esc;
228 index += utf8_char_len(&string[index]);
229 // is current char already too far away?
230 if (x < current)
231 break;
232 }
233 *actual_x = (int)current;
234 *char_offset = i; //index;
235
236 return NSERROR_OK;
237}
238
239
240/**
241 * Find where to split a string to make it fit a width.
242 *
243 * \param fstyle style for this text
244 * \param string UTF-8 string to measure
245 * \param length length of string, in bytes
246 * \param x width available
247 * \param char_offset updated to offset in string of actual_x, [1..length]
248 * \param actual_x updated to x coordinate of character closest to x
249 * \return true on success, false on error and error reported
250 *
251 * On exit, char_offset indicates first character after split point.
252 *
253 * Note: char_offset of 0 should never be returned.
254 *
255 * Returns:
256 * char_offset giving split point closest to x, where actual_x <= x
257 * else
258 * char_offset giving split point closest to x, where actual_x > x
259 *
260 * Returning char_offset == length means no split possible
261 */
263 const char *string, size_t length,
264 int x, size_t *char_offset, int *actual_x)
265{
266 NSLOG(netsurf, DEEPDEBUG, "(, '%s', %" PRIsizet ", %d, , )",
267 string, length, x);
268 int index = 0;
269 BFont font;
270
271 nsbeos_style_to_font(font, fstyle);
272 BString str(string);
273 int32 len = str.CountChars();
274 float escapements[len];
275 float esc = 0.0;
276 float current = 0.0;
277 float last_x = 0.0;
278 int i;
279 int last_space = 0;
280
281 font.GetEscapements(string, len, escapements);
282 // very slow but it should work
283 for (i = 0; string[index] && i < len; i++) {
284 if (string[index] == ' ') {
285 last_x = current;
286 last_space = index;
287 }
288 if (x < current && last_space != 0) {
289 *actual_x = (int)last_x;
290 *char_offset = last_space;
291 return NSERROR_OK;;
292 }
293 esc += escapements[i];
294 current = font.Size() * esc;
295 index += utf8_char_len(&string[index]);
296 }
297 *actual_x = MIN(*actual_x, (int)current);
298 *char_offset = index;
299
300 return NSERROR_OK;
301}
302
303
304/**
305 * Render a string.
306 *
307 * \param fstyle style for this text
308 * \param string UTF-8 string to measure
309 * \param length length of string
310 * \param x x coordinate
311 * \param y y coordinate
312 * \return true on success, false on error and error reported
313 */
314
316 const char *string, size_t length,
317 int x, int y)
318{
319 //fprintf(stderr, "%s(, '%s', %d, %d, %d, )\n", __FUNCTION__, string, length, x, y);
320 //CALLED();
321 BFont font;
322 rgb_color oldbg;
323 rgb_color background;
324 rgb_color foreground;
325 BView *view;
326 float size;
327
328 if (length == 0)
329 return true;
330
331 nsbeos_style_to_font(font, fstyle);
332 background = nsbeos_rgb_colour(fstyle->background);
333 foreground = nsbeos_rgb_colour(fstyle->foreground);
334
335 view = nsbeos_current_gc/*_lock*/();
336 if (view == NULL) {
337 beos_warn_user("No GC", 0);
338 return false;
339 }
340
341 oldbg = view->LowColor();
342 drawing_mode oldmode = view->DrawingMode();
343 view->SetLowColor(B_TRANSPARENT_32_BIT);
344
345 //view->SetScale() XXX
346
347//printf("nsfont_paint: Size: %f\n", font.Size());
348 size = (float)font.Size();
349#warning XXX use scale
350
351 view->SetFont(&font);
352 view->SetHighColor(foreground);
353 view->SetDrawingMode(B_OP_OVER);
354
355 BString line(string, length);
356
357 BPoint where(x, y + 1);
358 view->DrawString(line.String(), where);
359
360 view->SetDrawingMode(oldmode);
361 if (memcmp(&oldbg, &background, sizeof(rgb_color)))
362 view->SetLowColor(oldbg);
363
364 //nsbeos_current_gc_unlock();
365
366 return true;
367}
368
369
371 /*.width = */beos_font_width,
372 /*.position = */beos_font_position,
373 /*.split = */beos_font_split
374};
375
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:204
void nsbeos_style_to_font(BFont &font, const struct plot_font_style *fstyle)
Convert a font style to a PangoFontDescription.
Definition: font.cpp:54
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:262
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:151
static int utf8_char_len(const char *c)
Definition: font.cpp:170
struct gui_layout_table * beos_layout_table
Definition: font.cpp:376
static struct gui_layout_table layout_table
Definition: font.cpp:370
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:315
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.
Netsurf additional integer type formatting macros.
#define PRIsizet
c99 standard printf formatting for size_t type
Definition: inttypes.h:53
#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:161
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:335
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