示例#1
0
/*
** Some of the given glyph ids may refer to composite glyphs.
** This function adds all of the dependencies of those composite
** glyphs to the glyph id vector.  Michael Droettboom [06-07-07]
*/
void ttfont_add_glyph_dependencies(struct TTFONT *font, std::vector<int>& glyph_ids)
{
    std::sort(glyph_ids.begin(), glyph_ids.end());

    std::stack<int> glyph_stack;
    for (std::vector<int>::iterator i = glyph_ids.begin();
            i != glyph_ids.end(); ++i)
    {
        glyph_stack.push(*i);
    }

    while (glyph_stack.size())
    {
        int gind = glyph_stack.top();
        glyph_stack.pop();

        BYTE* glyph = find_glyph_data( font, gind );
        if (glyph != (BYTE*)NULL)
        {

            int num_ctr = getSHORT(glyph);
            if (num_ctr <= 0)   // This is a composite glyph
            {

                glyph += 10;
                USHORT flags = 0;

                do
                {
                    flags = getUSHORT(glyph);
                    glyph += 2;
                    gind = (int)getUSHORT(glyph);
                    glyph += 2;

                    std::vector<int>::iterator insertion =
                        std::lower_bound(glyph_ids.begin(), glyph_ids.end(), gind);
                    if (*insertion != gind)
                    {
                        glyph_ids.insert(insertion, gind);
                        glyph_stack.push(gind);
                    }

                    if (flags & ARG_1_AND_2_ARE_WORDS)
                    {
                        glyph += 4;
                    }
                    else
                    {
                        glyph += 2;
                    }

                    if (flags & WE_HAVE_A_SCALE)
                    {
                        glyph += 2;
                    }
                    else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
                    {
                        glyph += 4;
                    }
                    else if (flags & WE_HAVE_A_TWO_BY_TWO)
                    {
                        glyph += 8;
                    }
                }
                while (flags & MORE_COMPONENTS);
            }
        }
    }
}
示例#2
0
GlyphToType3::GlyphToType3(TTStreamWriter& stream, struct TTFONT *font, int charindex, bool embedded /* = false */)
{
    BYTE *glyph;

    tt_flags = NULL;
    xcoor = NULL;
    ycoor = NULL;
    epts_ctr = NULL;
    area_ctr = NULL;
    check_ctr = NULL;
    ctrset = NULL;
    stack_depth = 0;
    pdf_mode = font->target_type < 0;

    /* Get a pointer to the data. */
    glyph = find_glyph_data( font, charindex );

    /* If the character is blank, it has no bounding box, */
    /* otherwise read the bounding box. */
    if ( glyph == (BYTE*)NULL )
    {
        llx=lly=urx=ury=0;      /* A blank char has an all zero BoundingBox */
        num_ctr=0;              /* Set this for later if()s */
    }
    else
    {
        /* Read the number of contours. */
        num_ctr = getSHORT(glyph);

        /* Read PostScript bounding box. */
        llx = getFWord(glyph + 2);
        lly = getFWord(glyph + 4);
        urx = getFWord(glyph + 6);
        ury = getFWord(glyph + 8);

        /* Advance the pointer. */
        glyph += 10;
    }

    /* If it is a simple character, load its data. */
    if (num_ctr > 0)
    {
        load_char(font, glyph);
    }
    else
    {
        num_pts=0;
    }

    /* Consult the horizontal metrics table to determine */
    /* the character width. */
    if ( charindex < font->numberOfHMetrics )
    {
        advance_width = getuFWord( font->hmtx_table + (charindex * 4) );
    }
    else
    {
        advance_width = getuFWord( font->hmtx_table + ((font->numberOfHMetrics-1) * 4) );
    }

    /* Execute setcachedevice in order to inform the font machinery */
    /* of the character bounding box and advance width. */
    stack(stream, 7);
    if (pdf_mode)
    {
        if (!embedded) {
            stream.printf("%d 0 %d %d %d %d d1\n",
                          topost(advance_width),
                          topost(llx), topost(lly), topost(urx), topost(ury) );
        }
    }
    else if (font->target_type == PS_TYPE_42_3_HYBRID)
    {
        stream.printf("pop gsave .001 .001 scale %d 0 %d %d %d %d setcachedevice\n",
                      topost(advance_width),
                      topost(llx), topost(lly), topost(urx), topost(ury) );
    }
    else
    {
        stream.printf("%d 0 %d %d %d %d _sc\n",
                      topost(advance_width),
                      topost(llx), topost(lly), topost(urx), topost(ury) );
    }

    /* If it is a simple glyph, convert it, */
    /* otherwise, close the stack business. */
    if ( num_ctr > 0 )          /* simple */
    {
        PSConvert(stream);
    }
    else if ( num_ctr < 0 )     /* composite */
    {
        do_composite(stream, font, glyph);
    }

    if (font->target_type == PS_TYPE_42_3_HYBRID)
    {
        stream.printf("\ngrestore\n");
    }

    stack_end(stream);
}
示例#3
0
/*
** Emmit PostScript code for a composite character.
*/
void GlyphToType3::do_composite(TTStreamWriter& stream, struct TTFONT *font, BYTE *glyph)
{
    USHORT flags;
    USHORT glyphIndex;
    int arg1;
    int arg2;
    USHORT xscale;
    USHORT yscale;
    USHORT scale01;
    USHORT scale10;

    /* Once around this loop for each component. */
    do
    {
        flags = getUSHORT(glyph);       /* read the flags word */
        glyph += 2;

        glyphIndex = getUSHORT(glyph);  /* read the glyphindex word */
        glyph += 2;

        if (flags & ARG_1_AND_2_ARE_WORDS)
        {
            /* The tt spec. seems to say these are signed. */
            arg1 = getSHORT(glyph);
            glyph += 2;
            arg2 = getSHORT(glyph);
            glyph += 2;
        }
        else                    /* The tt spec. does not clearly indicate */
        {
            /* whether these values are signed or not. */
            arg1 = *(signed char *)(glyph++);
            arg2 = *(signed char *)(glyph++);
        }

        if (flags & WE_HAVE_A_SCALE)
        {
            xscale = yscale = getUSHORT(glyph);
            glyph += 2;
            scale01 = scale10 = 0;
        }
        else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
        {
            xscale = getUSHORT(glyph);
            glyph += 2;
            yscale = getUSHORT(glyph);
            glyph += 2;
            scale01 = scale10 = 0;
        }
        else if (flags & WE_HAVE_A_TWO_BY_TWO)
        {
            xscale = getUSHORT(glyph);
            glyph += 2;
            scale01 = getUSHORT(glyph);
            glyph += 2;
            scale10 = getUSHORT(glyph);
            glyph += 2;
            yscale = getUSHORT(glyph);
            glyph += 2;
        }
        else
        {
            xscale = yscale = scale01 = scale10 = 0;
        }

        /* Debugging */
#ifdef DEBUG_TRUETYPE
        stream.printf("%% flags=%d, arg1=%d, arg2=%d, xscale=%d, yscale=%d, scale01=%d, scale10=%d\n",
                      (int)flags,arg1,arg2,(int)xscale,(int)yscale,(int)scale01,(int)scale10);
#endif

        if (pdf_mode)
        {
            if ( flags & ARGS_ARE_XY_VALUES )
            {
                /* We should have been able to use 'Do' to reference the
                   subglyph here.  However, that doesn't seem to work with
                   xpdf or gs (only acrobat), so instead, this just includes
                   the subglyph here inline. */
                stream.printf("q 1 0 0 1 %d %d cm\n", topost(arg1), topost(arg2));
            }
            else
            {
                stream.printf("%% unimplemented shift, arg1=%d, arg2=%d\n",arg1,arg2);
            }
            GlyphToType3(stream, font, glyphIndex, true);
            if ( flags & ARGS_ARE_XY_VALUES )
            {
                stream.printf("\nQ\n");
            }
        }
        else
        {
            /* If we have an (X,Y) shif and it is non-zero, */
            /* translate the coordinate system. */
            if ( flags & ARGS_ARE_XY_VALUES )
            {
                if ( arg1 != 0 || arg2 != 0 )
                    stream.printf("gsave %d %d translate\n", topost(arg1), topost(arg2) );
            }
            else
            {
                stream.printf("%% unimplemented shift, arg1=%d, arg2=%d\n",arg1,arg2);
            }

            /* Invoke the CharStrings procedure to print the component. */
            stream.printf("false CharStrings /%s get exec\n",
                          ttfont_CharStrings_getname(font,glyphIndex));

            /* If we translated the coordinate system, */
            /* put it back the way it was. */
            if ( flags & ARGS_ARE_XY_VALUES && (arg1 != 0 || arg2 != 0) )
            {
                stream.puts("grestore ");
            }
        }

    }
    while (flags & MORE_COMPONENTS);

} /* end of do_composite() */
示例#4
0
void read_font(const char *filename, font_type_enum target_type, std::vector<int>& glyph_ids, TTFONT& font)
{
    BYTE *ptr;

    /* Decide what type of PostScript font we will be generating. */
    font.target_type = target_type;

    if (font.target_type == PS_TYPE_42)
    {
        bool has_low = false;
        bool has_high = false;

        for (std::vector<int>::const_iterator i = glyph_ids.begin();
                i != glyph_ids.end(); ++i)
        {
            if (*i > 255)
            {
                has_high = true;
                if (has_low) break;
            }
            else
            {
                has_low = true;
                if (has_high) break;
            }
        }

        if (has_high && has_low)
        {
            font.target_type = PS_TYPE_42_3_HYBRID;
        }
        else if (has_high && !has_low)
        {
            font.target_type = PS_TYPE_3;
        }
    }

    /* Save the file name for error messages. */
    font.filename=filename;

    /* Open the font file */
    if ( (font.file = fopen(filename,"rb")) == (FILE*)NULL )
    {
        throw TTException("Failed to open TrueType font");
    }

    /* Allocate space for the unvarying part of the offset table. */
    assert(font.offset_table == NULL);
    font.offset_table = (BYTE*)calloc( 12, sizeof(BYTE) );

    /* Read the first part of the offset table. */
    if ( fread( font.offset_table, sizeof(BYTE), 12, font.file ) != 12 )
    {
        throw TTException("TrueType font may be corrupt (reason 1)");
    }

    /* Determine how many directory entries there are. */
    font.numTables = getUSHORT( font.offset_table + 4 );
#ifdef DEBUG_TRUETYPE
    debug("numTables=%d",(int)font.numTables);
#endif

    /* Expand the memory block to hold the whole thing. */
    font.offset_table = (BYTE*)realloc( font.offset_table, sizeof(BYTE) * (12 + font.numTables * 16) );

    /* Read the rest of the table directory. */
    if ( fread( font.offset_table + 12, sizeof(BYTE), (font.numTables*16), font.file ) != (font.numTables*16) )
    {
        throw TTException("TrueType font may be corrupt (reason 2)");
    }

    /* Extract information from the "Offset" table. */
    font.TTVersion = getFixed( font.offset_table );

    /* Load the "head" table and extract information from it. */
    ptr = GetTable(&font, "head");
    try
    {
        font.MfrRevision = getFixed( ptr + 4 );           /* font revision number */
        font.unitsPerEm = getUSHORT( ptr + 18 );
        font.HUPM = font.unitsPerEm / 2;
#ifdef DEBUG_TRUETYPE
        debug("unitsPerEm=%d",(int)font.unitsPerEm);
#endif
        font.llx = topost2( getFWord( ptr + 36 ) );               /* bounding box info */
        font.lly = topost2( getFWord( ptr + 38 ) );
        font.urx = topost2( getFWord( ptr + 40 ) );
        font.ury = topost2( getFWord( ptr + 42 ) );
        font.indexToLocFormat = getSHORT( ptr + 50 );     /* size of 'loca' data */
        if (font.indexToLocFormat != 0 && font.indexToLocFormat != 1)
        {
            throw TTException("TrueType font is unusable because indexToLocFormat != 0");
        }
        if ( getSHORT(ptr+52) != 0 )
        {
            throw TTException("TrueType font is unusable because glyphDataFormat != 0");
        }
    }
    catch (TTException& )
    {
        free(ptr);
        throw;
    }
    free(ptr);

    /* Load information from the "name" table. */
    Read_name(&font);

    /* We need to have the PostScript table around. */
    assert(font.post_table == NULL);
    font.post_table = GetTable(&font, "post");
    font.numGlyphs = getUSHORT( font.post_table + 32 );

    /* If we are generating a Type 3 font, we will need to */
    /* have the 'loca' and 'glyf' tables arround while */
    /* we are generating the CharStrings. */
    if (font.target_type == PS_TYPE_3 || font.target_type == PDF_TYPE_3 ||
            font.target_type == PS_TYPE_42_3_HYBRID)
    {
        BYTE *ptr;                      /* We need only one value */
        ptr = GetTable(&font, "hhea");
        font.numberOfHMetrics = getUSHORT(ptr + 34);
        free(ptr);

        assert(font.loca_table == NULL);
        font.loca_table = GetTable(&font,"loca");
        assert(font.glyf_table == NULL);
        font.glyf_table = GetTable(&font,"glyf");
        assert(font.hmtx_table == NULL);
        font.hmtx_table = GetTable(&font,"hmtx");
    }

    if (glyph_ids.size() == 0)
    {
        glyph_ids.clear();
        glyph_ids.reserve(font.numGlyphs);
        for (int x = 0; x < font.numGlyphs; ++x)
        {
            glyph_ids.push_back(x);
        }
    }
    else if (font.target_type == PS_TYPE_3 ||
             font.target_type == PS_TYPE_42_3_HYBRID)
    {
        ttfont_add_glyph_dependencies(&font, glyph_ids);
    }

} /* end of insert_ttfont() */
示例#5
0
static int decodeSensor(char* raw, enum ws_types ws_type, float scale, float* var)
{
    float           fresult;
    uint16_t        usTemp;

    switch (ws_type)
    {
    case ub:
        if ((unsigned char)raw[0] == 0xFF)
        {
            // Deal with humidity < 10% problem by hard-coding to 9:
            fresult = 9;
        }
        else
        {
            fresult = (unsigned char)raw[0] * scale;
        }
        break;
    case us:
        usTemp = getUSHORT(raw);
        if (usTemp == 0xFFFF)
        {
            return ERROR;
        }
        fresult = usTemp * scale;
        break;
    case ss:
        if (((unsigned char)raw[0] == 0xFF) && ((unsigned char)raw[1] == 0xFF))
        {
            return ERROR;
        }
        fresult = getSHORT(raw) * scale;
        break;
    case pb:
        fresult = (unsigned char)raw[0];
        break;
    case wa:
        // wind average - 12 bits split across a byte and a nibble
        if (((unsigned char)raw[0] == 0xFF) && (((unsigned char)raw[2] & 0x0F) == 0x0F))
        {
            return ERROR;
        }
        fresult = (unsigned char)raw[0] + (((unsigned char)raw[2] & 0x0F) * 256);
        fresult = fresult * scale;
        break;
    case wg:
        // wind gust - 12 bits split across a byte and a nibble
        if (((unsigned char)raw[0] == 0xFF) && (((unsigned char)raw[1] & 0xF0) == 0xF0))
        {
            return ERROR;
        }
        fresult = (unsigned char)raw[0] + (((unsigned char)raw[1] & 0xF0) * 16);
        fresult = fresult * scale;
        break;
    case wd:
        if (((unsigned char)raw[0] & 0x80) == 0x80)
        {
            return ERROR;
        }
        fresult = (unsigned char)raw[0] * scale;
        fresult *= 22.5;
        break;
    default:
        fresult = ARCHIVE_VALUE_NULL;
        break;
    }

    *var = fresult;
    return OK;
}
示例#6
0
static int decodeSensor(char* raw, enum ws_types ws_type, float scale, float* var)
{
    float           fresult;
    unsigned short  usTemp;

    switch (ws_type)
    {
    case ub:
        if ((unsigned char)raw[0] == 0xFF)
        {
            return ERROR;
        }
        fresult = (unsigned char)raw[0] * scale;
        break;
    case us:
        usTemp = getUSHORT(raw);
        if (usTemp == 0xFFFF)
        {
            return ERROR;
        }
        fresult = usTemp * scale;
        break;
    case ss:
        if (((unsigned char)raw[0] == 0xFF) && ((unsigned char)raw[1] == 0xFF))
        {
            return ERROR;
        }
        fresult = getSHORT(raw) * scale;
        break;
    case pb:
        fresult = (unsigned char)raw[0];
        break;
    case wa:
        // wind average - 12 bits split across a byte and a nibble
        if (((unsigned char)raw[0] == 0xFF) && (((unsigned char)raw[2] & 0x0F) == 0x0F))
        {
            return ERROR;
        }
        fresult = (unsigned char)raw[0] + (((unsigned char)raw[2] & 0x0F) * 256);
        fresult = fresult * scale;
        break;
    case wg:
        // wind gust - 12 bits split across a byte and a nibble
        if (((unsigned char)raw[0] == 0xFF) && (((unsigned char)raw[1] & 0xF0) == 0xF0))
        {
            return ERROR;
        }
        fresult = (unsigned char)raw[0] + (((unsigned char)raw[1] & 0xF0) * 16);
        fresult = fresult * scale;
        break;
    case wd:
        if (((unsigned char)raw[0] & 0x80) == 0x80)
        {
            return ERROR;
        }
        fresult = (unsigned char)raw[0] * scale;
        fresult *= 22.5;
        break;
    default:
        fresult = -10000;
        break;
    }

    *var = fresult;
    return OK;
}