Ticket #13526: 0002-Fixes-13526-so-that-BFont-Blocks-properly-set-bitmas.patch

File 0002-Fixes-13526-so-that-BFont-Blocks-properly-set-bitmas.patch, 4.6 KB (added by dsizzle, 7 years ago)
  • src/servers/app/ServerFont.cpp

    From ab3604f492ed54861e0591d87a04529094fb46e1 Mon Sep 17 00:00:00 2001
    From: Dale Cieslak <dcieslak@yahoo.com>
    Date: Sun, 21 May 2017 23:39:22 +0000
    Subject: [PATCH 2/2] Fixes #13526 so that BFont::Blocks properly set bitmask
     for Unicode blocks in a font.
    
    ParseFcMap had several logic errors.
    - fixed variable being initialized in the wrong part of the loops
    - fixed problem of ANDing bit with 0x8 instead of 0x1
    - changed some variable names; 'foundStartBlock' implies a boolean but
    it is a block number, so it is now just 'startBlock'
    - added const BITS_PER_BLOCK for magic number 32
    - added short-circuit for empty full or partial blocks
    - initialized variables to -1 when 0 is a valid value
    - added code to handle when the end of a block is reached and a range
    was started but never finished.
    ---
     src/servers/app/ServerFont.cpp | 94 +++++++++++++++++++++++++++---------------
     1 file changed, 60 insertions(+), 34 deletions(-)
    
    diff --git a/src/servers/app/ServerFont.cpp b/src/servers/app/ServerFont.cpp
    index 74dd8f9..cd9015c 100644
    a b static  
    497497void
    498498ParseFcMap(FcChar32 charMap[], FcChar32 baseCodePoint, unicode_block& blocksForMap)
    499499{
     500    uint32 block = 0;
     501    const uint8 BITS_PER_BLOCK = 32;
     502    uint32 currentCodePoint = 0;
     503   
    500504    for (int i = 0; i < FC_CHARSET_MAP_SIZE; ++i) {
    501505        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) {
     506        int32 rangeStart = -1;
     507        int32 startBlock = -1;
     508        int32 endBlock = -1;
     509        uint32 startPoint = 0;
     510   
     511        currentCodePoint = baseCodePoint + block;
     512               
     513        for (int bit = 0; bit < BITS_PER_BLOCK; ++bit) {       
     514            if (curMapBlock == 0 && startBlock < 0)
     515                // if no more bits are set then short-circuit the loop
     516                break;
     517           
     518            if ((curMapBlock & 0x1) != 0 && rangeStart < 0) {
     519                rangeStart = bit;
     520                startPoint = currentCodePoint + rangeStart;
     521                startBlock = FindBlockForCodepoint(startPoint, 0);
     522                if (startBlock >= 0) {
     523                    blocksForMap = blocksForMap
     524                        | kUnicodeBlockMap[startBlock].block;
     525                }
     526            } else if (rangeStart >= 0 && startBlock >= 0) {
    521527                    // when we find an empty bit, that's the end of the range
    522                 uint32 endPoint = baseCodePoint + block + (bit - 1);
     528                uint32 endPoint = currentCodePoint + (bit - 1);
    523529
    524                 foundEndBlock = FindBlockForCodepoint(endPoint,
    525                     foundStartBlock);
     530                endBlock = FindBlockForCodepoint(endPoint,
     531                    startBlock);
    526532                    // start the binary search at the block where we found the
    527533                    // start codepoint to ideally find the end in the same
    528534                    // block.
    529                 ++foundStartBlock;
     535                ++startBlock;
    530536
    531                 while (foundStartBlock <= foundEndBlock) {
     537                while (startBlock <= endBlock) {
    532538                    // if the starting codepoint is found in a different block
    533539                    // than the ending codepoint, we should add all the blocks
    534540                    // inbetween.
    535541                    blocksForMap = blocksForMap
    536                         | kUnicodeBlockMap[foundStartBlock].block;
    537                     ++foundStartBlock;
     542                        | kUnicodeBlockMap[startBlock].block;
     543                    ++startBlock;
    538544                }
    539545
    540                 foundStartBlock = -1;
    541                 foundEndBlock = -1;
    542                 rangeStart = 0;
    543             } else {
    544                 foundStartBlock = -1;
    545                 rangeStart = 0;
    546             }
     546                startBlock = -1;
     547                endBlock = -1;
     548                rangeStart = -1;
     549            }
    547550
    548551            curMapBlock >>= 1;
    549552        }
     553       
     554        if (rangeStart >= 0 && startBlock >= 0) {
     555                // if we hit the end of the block and had
     556                // found a start of the range then we
     557                // should end the range at the end of the block
     558            uint32 endPoint = currentCodePoint + BITS_PER_BLOCK - 1;
     559
     560            endBlock = FindBlockForCodepoint(endPoint,
     561                startBlock);
     562                // start the binary search at the block where we found the
     563                // start codepoint to ideally find the end in the same
     564                // block.
     565            ++startBlock;
     566
     567            while (startBlock <= endBlock) {
     568                // if the starting codepoint is found in a different block
     569                // than the ending codepoint, we should add all the blocks
     570                // inbetween.
     571                blocksForMap = blocksForMap
     572                    | kUnicodeBlockMap[startBlock].block;
     573                ++startBlock;
     574            }
     575        }
    550576
    551         block += 32;
     577        block += BITS_PER_BLOCK;
    552578    }
    553579}
    554580