Break few dependencies on normal

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-03-15 22:12:34 +01:00
parent 7f837ea536
commit 53c648d2eb
6 changed files with 158 additions and 116 deletions

View file

@ -496,7 +496,8 @@ gfxmenu_mod_SOURCES = \
gfxmenu/gui_progress_bar.c \
gfxmenu/gui_util.c \
gfxmenu/gui_string_util.c \
gfxmenu/named_colors.c
gfxmenu/named_colors.c \
gfxmenu/font.c
gfxmenu_mod_CFLAGS = $(COMMON_CFLAGS)
gfxmenu_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -924,30 +924,6 @@ grub_font_get_height (grub_font_t font)
return font->ascent + font->descent + font->leading;
}
/* Get the width in pixels of the specified UTF-8 string, when rendered in
in the specified font (but falling back on other fonts for glyphs that
are missing). */
int
grub_font_get_string_width (grub_font_t font, const char *str)
{
int width;
struct grub_font_glyph *glyph;
grub_uint32_t code;
const grub_uint8_t *ptr;
for (ptr = (const grub_uint8_t *) str, width = 0;
grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0; )
{
glyph = grub_font_get_glyph_with_fallback (font, code);
if (glyph)
width += glyph->device_width;
else
width += unknown_glyph->device_width;
}
return width;
}
/* Get the glyph for FONT corresponding to the Unicode code point CODE.
Returns the ASCII glyph for the code if no other fonts are available.
The glyphs are cached once loaded. */
@ -1202,7 +1178,6 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
for (i = 0; i < glyph_id->ncomb; i++)
{
enum grub_comb_type combtype;
grub_int16_t space = 0;
grub_int16_t centerx = (bounds.width - combining_glyphs[i]->width) / 2
+ bounds.x;
@ -1210,10 +1185,9 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
if (!combining_glyphs[i])
continue;
/* CGJ is to avoid diacritics reordering. */
if (glyph_id->combining[i] == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
if (glyph_id->combining[i].code == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
continue;
combtype = grub_unicode_get_comb_type (glyph_id->combining[i]);
switch (combtype)
switch (glyph_id->combining[i].type)
{
case GRUB_UNICODE_COMB_OVERLAY:
do_blit (combining_glyphs[i],
@ -1324,7 +1298,7 @@ grub_font_construct_dry_run (grub_font_t hinted_font,
for (i = 0; i < glyph_id->ncomb; i++)
combining_glyphs[i]
= grub_font_get_glyph_with_fallback (main_glyph->font,
glyph_id->combining[i]);
glyph_id->combining[i].code);
}
blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs, device_width);
@ -1446,46 +1420,3 @@ grub_font_draw_glyph (struct grub_font_glyph *glyph,
glyph->width, glyph->height);
}
/* Draw a UTF-8 string of text on the current video render target.
The x coordinate specifies the starting x position for the first character,
while the y coordinate specifies the baseline position.
If the string contains a character that FONT does not contain, then
a glyph from another loaded font may be used instead. */
grub_err_t
grub_font_draw_string (const char *str, grub_font_t font,
grub_video_color_t color,
int left_x, int baseline_y)
{
int x;
struct grub_font_glyph *glyph;
grub_uint32_t *logical;
grub_ssize_t logical_len, visual_len;
struct grub_unicode_glyph *visual, *ptr;
logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0);
if (logical_len < 0)
return grub_errno;
visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual, 0, 0);
grub_free (logical);
if (visual_len < 0)
return grub_errno;
for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++)
{
grub_err_t err;
glyph = grub_font_construct_glyph (font, ptr);
if (!glyph)
return grub_errno;
err = grub_font_draw_glyph (glyph, color, x, baseline_y);
grub_free (glyph);
if (err)
return err;
x += glyph->device_width;
}
grub_free (visual);
return GRUB_ERR_NONE;
}

107
gfxmenu/font.c Normal file
View file

@ -0,0 +1,107 @@
/* font.c - Font API and font file loader. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/bufio.h>
#include <grub/dl.h>
#include <grub/file.h>
#include <grub/font.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/types.h>
#include <grub/video.h>
#include <grub/bitmap.h>
#include <grub/charset.h>
#include <grub/unicode.h>
#include <grub/fontformat.h>
/* Draw a UTF-8 string of text on the current video render target.
The x coordinate specifies the starting x position for the first character,
while the y coordinate specifies the baseline position.
If the string contains a character that FONT does not contain, then
a glyph from another loaded font may be used instead. */
grub_err_t
grub_font_draw_string (const char *str, grub_font_t font,
grub_video_color_t color,
int left_x, int baseline_y)
{
int x;
struct grub_font_glyph *glyph;
grub_uint32_t *logical;
grub_ssize_t logical_len, visual_len;
struct grub_unicode_glyph *visual, *ptr;
logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0);
if (logical_len < 0)
return grub_errno;
visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual, 0, 0);
grub_free (logical);
if (visual_len < 0)
return grub_errno;
for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++)
{
grub_err_t err;
glyph = grub_font_construct_glyph (font, ptr);
if (!glyph)
return grub_errno;
err = grub_font_draw_glyph (glyph, color, x, baseline_y);
grub_free (glyph);
if (err)
return err;
x += glyph->device_width;
}
grub_free (visual);
return GRUB_ERR_NONE;
}
/* Get the width in pixels of the specified UTF-8 string, when rendered in
in the specified font (but falling back on other fonts for glyphs that
are missing). */
int
grub_font_get_string_width (grub_font_t font, const char *str)
{
int width = 0;
grub_uint32_t *ptr;
grub_ssize_t logical_len;
grub_uint32_t *logical;
logical_len = grub_utf8_to_ucs4_alloc (str, &logical, 0);
if (logical_len < 0)
{
grub_errno = GRUB_ERR_NONE;
return 0;
}
for (ptr = logical; ptr < logical + logical_len;)
{
struct grub_unicode_glyph glyph;
ptr += grub_unicode_aglomerate_comb (ptr,
logical_len - (ptr - logical),
&glyph);
width += grub_font_get_constructed_device_width (font, &glyph);
grub_free (glyph.combining);
}
return width;
}

View file

@ -20,6 +20,8 @@
#define GRUB_BIDI_HEADER 1
#include <grub/types.h>
#include <grub/mm.h>
#include <grub/misc.h>
struct grub_unicode_compact_range
{
@ -78,7 +80,10 @@ struct grub_unicode_glyph
grub_uint16_t variant:9;
grub_uint8_t attributes:1;
grub_size_t ncomb;
grub_uint32_t *combining;
struct grub_unicode_combining {
grub_uint32_t code;
enum grub_comb_type type;
} *combining;
};
#define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1
@ -106,9 +111,39 @@ grub_unicode_get_comb_type (grub_uint32_t c);
grub_size_t
grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
struct grub_unicode_glyph *out);
struct grub_unicode_glyph *
grub_unicode_glyph_from_code (grub_uint32_t code);
struct grub_unicode_glyph *
grub_unicode_glyph_dup (const struct grub_unicode_glyph *in);
static inline struct grub_unicode_glyph *
grub_unicode_glyph_dup (const struct grub_unicode_glyph *in)
{
struct grub_unicode_glyph *out = grub_malloc (sizeof (*out));
if (!out)
return NULL;
grub_memcpy (out, in, sizeof (*in));
out->combining = grub_malloc (in->ncomb * sizeof (*in));
if (!out->combining)
{
grub_free (out);
return NULL;
}
grub_memcpy (out->combining, in->combining, in->ncomb * sizeof (*in));
return out;
}
static inline struct grub_unicode_glyph *
grub_unicode_glyph_from_code (grub_uint32_t code)
{
struct grub_unicode_glyph *ret;
ret = grub_malloc (sizeof (*ret));
if (!ret)
return NULL;
ret->base = code;
ret->variant = 0;
ret->attributes = 0;
ret->ncomb = 0;
ret->combining = 0;
return ret;
}
#endif

View file

@ -488,7 +488,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
comb_type = grub_unicode_get_comb_type (*ptr);
if (comb_type)
{
grub_uint32_t *n;
struct grub_unicode_combining *n;
unsigned j;
if (!haveout)
@ -499,7 +499,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
|| comb_type == GRUB_UNICODE_COMB_MN)
last_comb_pointer = out->ncomb;
n = grub_realloc (out->combining,
sizeof (grub_uint32_t) * (out->ncomb + 1));
sizeof (n[0]) * (out->ncomb + 1));
if (!n)
{
grub_errno = GRUB_ERR_NONE;
@ -507,14 +507,15 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
}
for (j = last_comb_pointer; j < out->ncomb; j++)
if (grub_unicode_get_comb_type (out->combining[j]) > comb_type)
if (out->combining[j].type > comb_type)
break;
grub_memmove (out->combining + j + 1,
out->combining + j,
(out->ncomb - j)
* sizeof (out->combining[0]));
out->combining = n;
out->combining[j] = *ptr;
out->combining[j].code = *ptr;
out->combining[j].type = comb_type;
out->ncomb++;
continue;
}
@ -946,40 +947,6 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical,
return visual_ptr - *visual_out;
}
struct grub_unicode_glyph *
grub_unicode_glyph_dup (const struct grub_unicode_glyph *in)
{
struct grub_unicode_glyph *out = grub_malloc (sizeof (*out));
if (!out)
return NULL;
grub_memcpy (out, in, sizeof (*in));
out->combining = grub_malloc (in->ncomb * sizeof (*in));
if (!out->combining)
{
grub_free (out);
return NULL;
}
grub_memcpy (out->combining, in->combining, in->ncomb * sizeof (*in));
return out;
}
struct grub_unicode_glyph *
grub_unicode_glyph_from_code (grub_uint32_t code)
{
struct grub_unicode_glyph *ret;
ret = grub_malloc (sizeof (*ret));
if (!ret)
return NULL;
ret->base = code;
ret->variant = 0;
ret->attributes = 0;
ret->ncomb = 0;
ret->combining = 0;
return ret;
}
static grub_uint32_t
map_code (grub_uint32_t in, struct grub_term_output *term)
{

View file

@ -267,6 +267,7 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
len - i, &glyph);
width = grub_term_getcharwidth (term, &glyph);
grub_free (glyph.combining);
if (x + width <= (int) (GRUB_TERM_LEFT_BORDER_X
+ grub_term_border_width (term)