Ticket #11518: 0001-Implementation-of-BFont-Blocks.patch

File 0001-Implementation-of-BFont-Blocks.patch, 20.3 KB (added by dsizzle, 7 years ago)

New, working patch

  • build/jam/BuildFeatures

    From 35455758262b1106fe4817418ffdee0bd36f18a6 Mon Sep 17 00:00:00 2001
    From: dsizzle <dcieslak@yahoo.com>
    Date: Thu, 10 Mar 2016 21:38:32 -0800
    Subject: [PATCH] Implementation of BFont::Blocks
    
    BFont::Blocks is now implemented in ServerFont, via a call through the
    app_server.  It uses fontconfig to iterate through a charset of a font
    and stores the defined blocks in a bitmap.
    
    A new API was added, BFont::IncludesBlock, that will allow for arbitrary
    testing of a given Unicode block. Since nothing is cached, searching
    through an entire charset for a series of Unicode blocks can be quite
    slow. In a given block there may be only 1 or 2 characters actually
    defined so every character within a block needs to be checked until one
    is found, which in a degenerate case will mean the entire block is
    checked.
    ---
     build/jam/BuildFeatures                    |  15 +++
     build/jam/OptionalPackages                 |   4 +-
     headers/os/interface/Font.h                |  13 +-
     headers/os/interface/UnicodeBlockObjects.h |  80 +++++++++++-
     headers/private/app/ServerProtocol.h       |   4 +-
     src/kits/interface/Font.cpp                |  39 +++++-
     src/servers/app/Jamfile                    |  17 ++-
     src/servers/app/ProfileMessageSupport.cpp  |   4 +-
     src/servers/app/ServerApp.cpp              |  65 ++++++++++
     src/servers/app/ServerFont.cpp             | 192 +++++++++++++++++++++++++++++
     src/servers/app/ServerFont.h               |   2 +
     11 files changed, 425 insertions(+), 10 deletions(-)
    
    diff --git a/build/jam/BuildFeatures b/build/jam/BuildFeatures
    index 9da6bc9..cc69e68 100644
    a b if [ IsPackageAvailable freetype_devel ] {  
    303303    Echo "Freetype support not available on $(TARGET_PACKAGING_ARCH)" ;
    304304}
    305305
     306# fontconfig
     307if [ IsPackageAvailable fontconfig_devel ] {
     308    ExtractBuildFeatureArchives fontconfig :
     309        file: base fontconfig
     310            runtime: lib
     311        file: devel fontconfig_devel
     312            depends: base
     313            library: $(developLibDir)/libfontconfig.so
     314            headers: $(developHeadersDir) $(developHeadersDir)/fontconfig
     315        ;
     316
     317    EnableBuildFeatures fontconfig ;
     318} else {
     319    Echo "fontconfig support not available on $(TARGET_PACKAGING_ARCH)" ;
     320}
    306321
    307322# Gutenprint
    308323if [ IsPackageAvailable gutenprint_devel ] {
  • build/jam/OptionalPackages

    diff --git a/build/jam/OptionalPackages b/build/jam/OptionalPackages
    index 513c2be..53bc926 100644
    a b if [ IsOptionalHaikuImagePackageAdded Development ] {  
    100100    local architectureObject ;
    101101    for architectureObject in [ MultiArchSubDirSetup ] {
    102102        on $(architectureObject) {
    103             AddHaikuImagePackages curl_devel ffmpeg_devel freetype_devel
    104                 glu_devel jpeg_devel libpng16_devel zlib_devel ;
     103            AddHaikuImagePackages curl_devel ffmpeg_devel fontconfig_devel
     104                freetype_devel glu_devel jpeg_devel libpng16_devel zlib_devel ;
    105105        }
    106106    }
    107107}
  • headers/os/interface/Font.h

    diff --git a/headers/os/interface/Font.h b/headers/os/interface/Font.h
    index eb7d59c..5277950 100644
    a b  
    11/*
    2  * Copyright 2005-2015, Haiku, Inc. All rights reserved.
     2 * Copyright 2005-2016, Haiku, Inc. All rights reserved.
    33 * Distributed under the terms of the MIT License.
    44 */
    55#ifndef _FONT_H_
    private:  
    120120};
    121121
    122122
     123struct unicode_block_range {
     124    uint32                  start;
     125    uint32                  end;
     126    const unicode_block&    block;
     127
     128    uint32 Count() const { return end + 1 - start; }
     129};
     130
     131
    123132struct edge_info {
    124133    float   left;
    125134    float   right;
    public:  
    201210            bool                IsFullAndHalfFixed() const;
    202211            BRect               BoundingBox() const;
    203212            unicode_block       Blocks() const;
     213            bool                IncludesBlock(uint32 start, uint32 end) const;
    204214            font_file_format    FileFormat() const;
    205215
    206216            int32               CountTuned() const;
    unicode_block::operator=(const unicode_block& block)  
    371381{
    372382    fData[0] = block.fData[0];
    373383    fData[1] = block.fData[1];
     384
    374385    return *this;
    375386}
    376387
  • headers/os/interface/UnicodeBlockObjects.h

    diff --git a/headers/os/interface/UnicodeBlockObjects.h b/headers/os/interface/UnicodeBlockObjects.h
    index ed5061e..2ea87c5 100644
    a b  
    11/*
    2  * Copyright 2001-2009, Haiku, Inc. All rights reserved.
     2 * Copyright 2001-2016, Haiku, Inc. All rights reserved.
    33 * Distributed under the terms of the MIT License.
    44 */
    55#ifndef _UNICODEBLOCKOBJECTS_H
     
    1010
    1111
    1212// Unicode block list with their unicode encoding range
     13//
     14// Original BeOS-compatible blocks
    1315const unicode_block B_BASIC_LATIN_BLOCK(                    /* 0000 - 007F          */  0x0000000000000000LL, 0x0000000000000001LL);
    1416const unicode_block B_LATIN1_SUPPLEMENT_BLOCK(              /* 0080 - 00FF          */  0x0000000000000000LL, 0x0000000000000002LL);
    1517const unicode_block B_LATIN_EXTENDED_A_BLOCK(               /* 0100 - 017F          */  0x0000000000000000LL, 0x0000000000000004LL);
    const unicode_block B_HALFWIDTH_AND_FULLWIDTH_FORMS_BLOCK( /* FF00 - FFEF */ 0  
    8284const unicode_block B_SPECIALS_BLOCK(                       /* FEFF and FFF0 - FFFF */  0x0000000000000020LL, 0x0000000000000000LL);
    8385const unicode_block B_TIBETAN_BLOCK(                        /* 0F00 - 0FBF          */  0x0000000000000040LL, 0x0000000000000000LL);
    8486
     87
     88const unicode_block_range kUnicodeBlockMap[] = {
     89    {0x0000, 0x007f, B_BASIC_LATIN_BLOCK },
     90    {0x0080, 0x00ff, B_LATIN1_SUPPLEMENT_BLOCK },
     91    {0x0100, 0x017f, B_LATIN_EXTENDED_A_BLOCK },
     92    {0x0180, 0x024f, B_LATIN_EXTENDED_B_BLOCK },
     93    {0x0250, 0x02af, B_IPA_EXTENSIONS_BLOCK },
     94    {0x02b0, 0x02ff, B_SPACING_MODIFIER_LETTERS_BLOCK },
     95    {0x0300, 0x036f, B_COMBINING_DIACRITICAL_MARKS_BLOCK },
     96    {0x0370, 0x03cf, B_BASIC_GREEK_BLOCK },
     97    {0x03d0, 0x03ff, B_GREEK_SYMBOLS_AND_COPTIC_BLOCK },
     98    {0x0400, 0x04ff, B_CYRILLIC_BLOCK },
     99    {0x0530, 0x058f, B_ARMENIAN_BLOCK },
     100    {0x0590, 0x05cf, B_BASIC_HEBREW_BLOCK },
     101    {0x05d0, 0x05ff, B_HEBREW_EXTENDED_BLOCK },
     102    {0x0600, 0x0670, B_BASIC_ARABIC_BLOCK },
     103    {0x0671, 0x06ff, B_ARABIC_EXTENDED_BLOCK },
     104    {0x0900, 0x097f, B_DEVANAGARI_BLOCK },
     105    {0x0980, 0x09ff, B_BENGALI_BLOCK },
     106    {0x0a00, 0x0a7f, B_GURMUKHI_BLOCK },
     107    {0x0a80, 0x0aff, B_GUJARATI_BLOCK },
     108    {0x0b00, 0x0b7f, B_ORIYA_BLOCK },
     109    {0x0b80, 0x0bff, B_TAMIL_BLOCK },
     110    {0x0c00, 0x0c7f, B_TELUGU_BLOCK },
     111    {0x0c80, 0x0cff, B_KANNADA_BLOCK},
     112    {0x0d00, 0x0d7f, B_MALAYALAM_BLOCK},
     113    {0x0e00, 0x0e7f, B_THAI_BLOCK},
     114    {0x0e80, 0x0eff, B_LAO_BLOCK},
     115    {0x0f00, 0x0fff, B_TIBETAN_BLOCK},
     116    {0x10a0, 0x10ff, B_BASIC_GEORGIAN_BLOCK},
     117    {0x1100, 0x11ff, B_HANGUL_JAMO_BLOCK},
     118    {0x1e00, 0x1eff, B_LATIN_EXTENDED_ADDITIONAL_BLOCK},
     119    {0x1f00, 0x1fff, B_GREEK_EXTENDED_BLOCK},
     120    {0x2000, 0x206f, B_GENERAL_PUNCTUATION_BLOCK},
     121    {0x2070, 0x209f, B_SUPERSCRIPTS_AND_SUBSCRIPTS_BLOCK},
     122    {0x20a0, 0x20cf, B_CURRENCY_SYMBOLS_BLOCK},
     123    {0x20d0, 0x20ff, B_COMBINING_MARKS_FOR_SYMBOLS_BLOCK},
     124    {0x2100, 0x214f, B_LETTERLIKE_SYMBOLS_BLOCK},
     125    {0x2150, 0x218f, B_NUMBER_FORMS_BLOCK},
     126    {0x2190, 0x21ff, B_ARROWS_BLOCK},
     127    {0x2200, 0x22ff, B_MATHEMATICAL_OPERATORS_BLOCK},
     128    {0x2300, 0x23ff, B_MISCELLANEOUS_TECHNICAL_BLOCK},
     129    {0x2400, 0x243f, B_CONTROL_PICTURES_BLOCK},
     130    {0x2440, 0x245f, B_OPTICAL_CHARACTER_RECOGNITION_BLOCK},
     131    {0x2460, 0x24ff, B_ENCLOSED_ALPHANUMERICS_BLOCK},
     132    {0x2500, 0x257f, B_BOX_DRAWING_BLOCK},
     133    {0x2580, 0x259f, B_BLOCK_ELEMENTS_BLOCK},
     134    {0x25a0, 0x25ff, B_GEOMETRIC_SHAPES_BLOCK},
     135    {0x2600, 0x26ff, B_MISCELLANEOUS_SYMBOLS_BLOCK},
     136    {0x2700, 0x27bf, B_DINGBATS_BLOCK},
     137    {0x3000, 0x303f, B_CJK_SYMBOLS_AND_PUNCTUATION_BLOCK},
     138    {0x3040, 0x309f, B_HIRAGANA_BLOCK},
     139    {0x30a0, 0x30ff, B_KATAKANA_BLOCK},
     140    {0x3100, 0x312f, B_BOPOMOFO_BLOCK},
     141    {0x3130, 0x318f, B_HANGUL_COMPATIBILITY_JAMO_BLOCK},
     142    {0x3190, 0x319f, B_CJK_MISCELLANEOUS_BLOCK},
     143    {0x3200, 0x32ff, B_ENCLOSED_CJK_LETTERS_AND_MONTHS_BLOCK},
     144    {0x3300, 0x33ff, B_CJK_COMPATIBILITY_BLOCK},
     145    {0x4e00, 0x9fff, B_CJK_UNIFIED_IDEOGRAPHS_BLOCK},
     146    {0xd800, 0xdb7f, B_HIGH_SURROGATES_BLOCK},
     147    {0xdc00, 0xdfff, B_LOW_SURROGATES_BLOCK},
     148    {0xe000, 0xf8ff, B_PRIVATE_USE_AREA_BLOCK},
     149    {0xf900, 0xfaff, B_CJK_COMPATIBILITY_IDEOGRAPHS_BLOCK},
     150    {0xfb00, 0xfb4f, B_ALPHABETIC_PRESENTATION_FORMS_BLOCK},
     151    {0xfb50, 0xfdff, B_ARABIC_PRESENTATION_FORMS_A_BLOCK},
     152    {0xfe20, 0xfe2f, B_COMBINING_HALF_MARKS_BLOCK},
     153    {0xfe30, 0xfe4f, B_CJK_COMPATIBILITY_FORMS_BLOCK},
     154    {0xfe50, 0xfe6f, B_SMALL_FORM_VARIANTS_BLOCK},
     155    {0xfe70, 0xfeff, B_ARABIC_PRESENTATION_FORMS_B_BLOCK},
     156    {0xff00, 0xffef, B_HALFWIDTH_AND_FULLWIDTH_FORMS_BLOCK},
     157    {0xfff0, 0xffff, B_SPECIALS_BLOCK}
     158};
     159
     160const uint32 kNumUnicodeBlockRanges
     161    = sizeof(kUnicodeBlockMap) / sizeof(kUnicodeBlockMap[0]);
     162
    85163#endif  // _UNICODEBLOCKOBJECTS_H
  • headers/private/app/ServerProtocol.h

    diff --git a/headers/private/app/ServerProtocol.h b/headers/private/app/ServerProtocol.h
    index 73b0a7c..580bb17 100644
    a b  
    11/*
    2  * Copyright 2001-2015, Haiku.
     2 * Copyright 2001-2016, Haiku.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
    enum {  
    143143    AS_GET_HAS_GLYPHS,
    144144    AS_GET_GLYPH_SHAPES,
    145145    AS_GET_TRUNCATED_STRINGS,
     146    AS_GET_UNICODE_BLOCKS,
     147    AS_GET_HAS_UNICODE_BLOCK,
    146148
    147149    // Screen methods
    148150    AS_VALID_SCREEN_ID,
  • src/kits/interface/Font.cpp

    diff --git a/src/kits/interface/Font.cpp b/src/kits/interface/Font.cpp
    index 804307f..6fde680 100644
    a b BFont::BoundingBox() const  
    839839unicode_block
    840840BFont::Blocks() const
    841841{
    842     // TODO: Add Block support
    843     return unicode_block(~0LL, ~0LL);
     842    BPrivate::AppServerLink link;
     843    link.StartMessage(AS_GET_UNICODE_BLOCKS);
     844    link.Attach<uint16>(fFamilyID);
     845    link.Attach<uint16>(fStyleID);
     846   
     847    int32 status;
     848    if (link.FlushWithReply(status) != B_OK
     849        || status != B_OK) {
     850        return unicode_block(~0LL, ~0LL);
     851    }
     852   
     853    unicode_block blocksForFont;
     854    link.Read<unicode_block>(&blocksForFont);
     855   
     856    return blocksForFont;
     857}
     858
     859bool
     860BFont::IncludesBlock(uint32 start, uint32 end) const
     861{
     862    BPrivate::AppServerLink link;
     863    link.StartMessage(AS_GET_HAS_UNICODE_BLOCK);
     864    link.Attach<uint16>(fFamilyID);
     865    link.Attach<uint16>(fStyleID);
     866    link.Attach<uint32>(start);
     867    link.Attach<uint32>(end);
     868   
     869    int32 status;
     870    if (link.FlushWithReply(status) != B_OK
     871        || status != B_OK) {
     872        return false;
     873    }
     874   
     875    bool hasBlock;
     876    link.Read<bool>(&hasBlock);
     877
     878    return hasBlock;
    844879}
    845880
    846881
  • src/servers/app/Jamfile

    diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile
    index 8f567ab..04c4afa 100644
    a b local font_src =  
    3232    ;
    3333
    3434UseBuildFeatureHeaders freetype ;
    35 Includes [ FGristFiles AppServer.cpp BitmapManager.cpp Canvas.cpp
     35if [ FIsBuildFeatureEnabled fontconfig ] {
     36    SubDirC++Flags -DFONTCONFIG_ENABLED ;
     37    UseBuildFeatureHeaders fontconfig ;
     38    Includes [ FGristFiles AppServer.cpp BitmapManager.cpp Canvas.cpp
     39    ClientMemoryAllocator.cpp Desktop.cpp DesktopSettings.cpp
     40    DrawState.cpp DrawingEngine.cpp Layer.cpp PictureBoundingBoxPlayer.cpp
     41    ServerApp.cpp ServerBitmap.cpp ServerCursor.cpp ServerFont.cpp
     42    ServerPicture.cpp ServerWindow.cpp View.cpp Window.cpp WorkspacesView.cpp
     43    $(decorator_src) $(font_src) ]
     44    : [ BuildFeatureAttribute freetype : headers ]
     45      [ BuildFeatureAttribute fontconfig : headers ] ;
     46} else {
     47    Includes [ FGristFiles AppServer.cpp BitmapManager.cpp Canvas.cpp
    3648    ClientMemoryAllocator.cpp Desktop.cpp DesktopSettings.cpp
    3749    DrawState.cpp DrawingEngine.cpp Layer.cpp PictureBoundingBoxPlayer.cpp
    3850    ServerApp.cpp ServerBitmap.cpp ServerCursor.cpp ServerFont.cpp
    3951    ServerPicture.cpp ServerWindow.cpp View.cpp Window.cpp WorkspacesView.cpp
    4052    $(decorator_src) $(font_src) ]
    4153    : [ BuildFeatureAttribute freetype : headers ] ;
    42 
     54}
    4355
    4456local BROKEN_64 = ;
    4557if $(TARGET_ARCH) != x86_64 {
    Server app_server :  
    103115    libaslocal.a $(BROKEN_64)libasremote.a $(BROKEN_64)libashtml5.a
    104116    libasdrawing.a libpainter.a libagg.a
    105117    [ BuildFeatureAttribute freetype : library ]
     118    [ BuildFeatureAttribute fontconfig : library ]
    106119    libstackandtile.a liblinprog.a libtextencoding.so shared
    107120    [ TargetLibstdc++ ]
    108121
  • src/servers/app/ProfileMessageSupport.cpp

    diff --git a/src/servers/app/ProfileMessageSupport.cpp b/src/servers/app/ProfileMessageSupport.cpp
    index f48f3bd..4f331c2 100644
    a b  
    11/*
    2  * Copyright 2007-2009, Haiku Inc. All rights reserved.
     2 * Copyright 2007-2016, Haiku Inc. All rights reserved.
    33 * Distributed under the terms of the MIT License.
    44 *
    55 * Authors:
    string_for_message_code(uint32 code, BString& string)  
    125125        CODE(AS_GET_HAS_GLYPHS);
    126126        CODE(AS_GET_GLYPH_SHAPES);
    127127        CODE(AS_GET_TRUNCATED_STRINGS);
     128        CODE(AS_GET_UNICODE_BLOCKS);
     129        CODE(AS_GET_HAS_UNICODE_BLOCK);
    128130
    129131        // Screen methods
    130132        CODE(AS_VALID_SCREEN_ID);
  • src/servers/app/ServerApp.cpp

    diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp
    index d3258e5..a69c1d2 100644
    a b ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)  
    20282028            break;
    20292029        }
    20302030
     2031        case AS_GET_UNICODE_BLOCKS:
     2032        {
     2033            FTRACE(("ServerApp %s: AS_GET_UNICODE_BLOCKS\n", Signature()));
     2034           
     2035            // Attached Data:
     2036            // 1) uint16 family ID
     2037            // 2) uint16 style ID
     2038           
     2039            // Returns:
     2040            // 1) unicode_block - bitfield of Unicode blocks in font
     2041
     2042            uint16 familyID, styleID;
     2043            link.Read<uint16>(&familyID);
     2044            link.Read<uint16>(&styleID);
     2045           
     2046            ServerFont font;
     2047            status_t status = font.SetFamilyAndStyle(familyID, styleID);
     2048            if (status == B_OK) {
     2049                unicode_block blocksForFont;
     2050                font.GetUnicodeBlocks(blocksForFont);
     2051               
     2052                fLink.StartMessage(B_OK);
     2053                fLink.Attach<unicode_block>(blocksForFont);
     2054            } else
     2055                fLink.StartMessage(status);
     2056
     2057            fLink.Flush();
     2058            break;
     2059        }
     2060           
     2061        case AS_GET_HAS_UNICODE_BLOCK:
     2062        {
     2063            FTRACE(("ServerApp %s: AS_INCLUDES_UNICODE_BLOCK\n", Signature()));
     2064           
     2065            // Attached Data:
     2066            // 1) uint16 family ID
     2067            // 2) uint16 style ID
     2068            // 3 uint32 start of unicode block
     2069            // 4) uint32 end of unicode block
     2070           
     2071            // Returns:
     2072            // 1) bool - whether or not font includes specified block range
     2073
     2074            uint16 familyID, styleID;
     2075            uint32 start, end;
     2076            link.Read<uint16>(&familyID);
     2077            link.Read<uint16>(&styleID);
     2078            link.Read<uint32>(&start);
     2079            link.Read<uint32>(&end);
     2080           
     2081            ServerFont font;
     2082            status_t status = font.SetFamilyAndStyle(familyID, styleID);
     2083            if (status == B_OK) {
     2084                bool hasBlock;
     2085               
     2086                status = font.IncludesUnicodeBlock(start, end, hasBlock);
     2087                fLink.StartMessage(status);
     2088                fLink.Attach<bool>(hasBlock);
     2089            } else
     2090                fLink.StartMessage(status);
     2091
     2092            fLink.Flush();
     2093            break;
     2094        }
     2095       
    20312096        case AS_GET_GLYPH_SHAPES:
    20322097        {
    20332098            FTRACE(("ServerApp %s: AS_GET_GLYPH_SHAPES\n", Signature()));
  • src/servers/app/ServerFont.cpp

    diff --git a/src/servers/app/ServerFont.cpp b/src/servers/app/ServerFont.cpp
    index d84068c..bfc12d3 100644
    a b  
    2222#include FT_GLYPH_H
    2323#include FT_OUTLINE_H
    2424
     25#ifdef FONTCONFIG_ENABLED
     26
     27#include <fontconfig.h>
     28#include <fcfreetype.h>
     29
     30#endif // FONTCONFIG_ENABLED
     31
    2532#include <Shape.h>
    2633#include <String.h>
     34#include <UnicodeBlockObjects.h>
    2735#include <UTF8.h>
    2836
    2937#include <agg_bounding_rect.h>
    ServerFont::GetGlyphShapes(const char charArray[], int32 numChars,  
    437445}
    438446
    439447
     448#ifdef FONTCONFIG_ENABLED
     449
     450/*!
     451    \brief For a given codepoint, do a binary search of the defined unicode
     452    blocks to figure out which one contains the codepoint.
     453    \param codePoint is the point to find
     454    \param startGuess is the starting point for the binary search (default 0)
     455*/
     456static
     457int32
     458FindBlockForCodepoint(uint32 codePoint, uint32 startGuess)
     459{
     460    uint32 min = 0;
     461    uint32 max = kNumUnicodeBlockRanges;
     462    uint32 guess = (max + min) / 2;
     463
     464    if (startGuess > 0)
     465        guess = startGuess;
     466
     467    if (codePoint > kUnicodeBlockMap[max-1].end)
     468        return -1;
     469
     470    while ((max >= min) && (guess < kNumUnicodeBlockRanges)) {
     471        uint32 start = kUnicodeBlockMap[guess].start;
     472        uint32 end = kUnicodeBlockMap[guess].end;
     473
     474        if (start <= codePoint && end >= codePoint)
     475            return guess;
     476
     477        if (end < codePoint) {
     478            min = guess + 1;
     479        } else {
     480            max = guess - 1;
     481        }
     482
     483        guess = (max + min) / 2;
     484    }
     485
     486    return -1;
     487}
     488
     489/*!
     490    \brief parses charmap from fontconfig.  See fontconfig docs for FcCharSetFirstPage
     491    and FcCharSetNextPage for details on format.
     492    \param charMap is a fontconfig character map
     493    \param baseCodePoint is the base codepoint returned by fontconfig
     494    \param blocksForMap is a unicode_block to store the bitmap of contained blocks
     495*/
     496static
     497void
     498ParseFcMap(FcChar32 charMap[], FcChar32 baseCodePoint, unicode_block& blocksForMap)
     499{
     500    for (int i = 0; i < FC_CHARSET_MAP_SIZE; ++i) {
     501        FcChar32 curMapBlock = charMap[i];
     502        uint32 rangeStart = 0;
     503        uint32 block = 0;
     504
     505        for (int bit = 0; bit < 32; ++bit) {
     506            uint32 startPoint = 0;
     507            int32 foundStartBlock = -1;
     508            int32 foundEndBlock = -1;
     509
     510            if ((curMapBlock & 0x8) != 0) {
     511                if (rangeStart == 0) {
     512                    rangeStart = bit;
     513                    startPoint = baseCodePoint + block + (rangeStart);
     514                    foundStartBlock = FindBlockForCodepoint(startPoint, 0);
     515                    if (foundStartBlock >= 0) {
     516                        blocksForMap = blocksForMap
     517                            | kUnicodeBlockMap[foundStartBlock].block;
     518                    }
     519                }
     520            } else if (rangeStart > 0 && foundStartBlock > 0) {
     521                    // when we find an empty bit, that's the end of the range
     522                uint32 endPoint = baseCodePoint + block + (bit - 1);
     523
     524                foundEndBlock = FindBlockForCodepoint(endPoint,
     525                    foundStartBlock);
     526                    // start the binary search at the block where we found the
     527                    // start codepoint to ideally find the end in the same
     528                    // block.
     529                ++foundStartBlock;
     530
     531                while (foundStartBlock <= foundEndBlock) {
     532                    // if the starting codepoint is found in a different block
     533                    // than the ending codepoint, we should add all the blocks
     534                    // inbetween.
     535                    blocksForMap = blocksForMap
     536                        | kUnicodeBlockMap[foundStartBlock].block;
     537                    ++foundStartBlock;
     538                }
     539
     540                foundStartBlock = -1;
     541                foundEndBlock = -1;
     542                rangeStart = 0;
     543            } else {
     544                foundStartBlock = -1;
     545                rangeStart = 0;
     546            }
     547
     548            curMapBlock >>= 1;
     549        }
     550
     551        block += 32;
     552    }
     553}
     554
     555#endif // FONTCONFIG_ENABLED
     556
     557
     558/*!
     559    \brief Gets a bitmap that indicates which Unicode blocks are in the font.
     560    \param unicode_block to store bitmap in
     561    \return B_OK; bitmap will be empty if something went wrong
     562*/
     563status_t
     564ServerFont::GetUnicodeBlocks(unicode_block& blocksForFont)
     565{
     566    blocksForFont = unicode_block();
     567
     568#ifdef FONTCONFIG_ENABLED
     569    FT_Face face = GetTransformedFace(true, true);
     570    if (face == NULL)
     571        return B_ERROR;
     572
     573    FcCharSet *charSet = FcFreeTypeCharSet(face, NULL);
     574    if (charSet == NULL)
     575        return B_ERROR;
     576
     577    FcChar32 charMap[FC_CHARSET_MAP_SIZE];
     578    FcChar32 next = 0;
     579    FcChar32 baseCodePoint = FcCharSetFirstPage(charSet, charMap, &next);
     580
     581    while ((baseCodePoint != FC_CHARSET_DONE) && (next != FC_CHARSET_DONE)) {
     582        ParseFcMap(charMap, baseCodePoint, blocksForFont);
     583        baseCodePoint = FcCharSetNextPage(charSet, charMap, &next);
     584    }
     585
     586#endif // FONTCONFIG_ENABLED
     587
     588    return B_OK;
     589}
     590
     591/*!
     592    \brief Checks if a unicode block specified by a start and end point is defined
     593    in the current font
     594    \param start of unicode block
     595    \param end of unicode block
     596    \param hasBlock boolean to store whether the font contains the specified block
     597    \return B_OK; hasBlock will be false if something goes wrong
     598*/
     599status_t
     600ServerFont::IncludesUnicodeBlock(uint32 start, uint32 end, bool& hasBlock)
     601{
     602    hasBlock = false;
     603
     604#ifdef FONTCONFIG_ENABLED
     605    FT_Face face = GetTransformedFace(true, true);
     606    if (face == NULL)
     607        return B_ERROR;
     608
     609    FcCharSet *charSet = FcFreeTypeCharSet(face, NULL);
     610    if (charSet == NULL)
     611        return B_ERROR;
     612
     613    uint32 curCodePoint = start;
     614
     615    while (curCodePoint <= end && hasBlock == false) {
     616        // loop through range; if any character in the range is in the charset
     617        // then the block is represented.
     618        if (FcCharSetHasChar(charSet, (FcChar32)curCodePoint) == FcTrue) {
     619            hasBlock = true;
     620            break;
     621        }
     622
     623        ++curCodePoint;
     624    }
     625
     626#endif // FONTCONFIG_ENABLED
     627
     628    return B_OK;
     629}
     630
     631
    440632class HasGlyphsConsumer {
    441633 public:
    442634    HasGlyphsConsumer(bool* hasArray)
  • src/servers/app/ServerFont.h

    diff --git a/src/servers/app/ServerFont.h b/src/servers/app/ServerFont.h
    index b04a7e3..8d63cbf 100644
    a b class ServerFont {  
    163163                                               float width) const;
    164164
    165165            Transformable       EmbeddedTransformation() const;
     166            status_t            GetUnicodeBlocks(unicode_block &blocksForFont);
     167            status_t            IncludesUnicodeBlock(uint32 start, uint32 end, bool &hasBlock);
    166168
    167169protected:
    168170    friend class FontStyle;