⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 font.cc

📁 Linux下比较早的基于命令行的DVD播放器
💻 CC
字号:
//// Copyright (c) 2005 by Istv醤 V醨adi//// This file is part of dxr3Player, a DVD player written specifically // for the DXR3 (aka Hollywood+) decoder card, but now handles other// hardware as well. These files contain a (mostly) user-space driver // for the Unichrome board found on Via's EPIA motherboards.//// The information for implementing this driver has been gathered// from the following sources://// - The DirectFB Unichrome driver//   Copyright (c) 2003 Andreas Robinson, All rights reserved.//// - Andreas Robinson's MPEG-2 decoder for the Unichrome board.//   Copyright (c) 2003 Andreas Robinson, All rights reserved.//// - Via's Unichrome Framebuffer driver//   Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.//   Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.// This program 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 2 of the License, or// (at your option) any later version.//// This program 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 this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA//------------------------------------------------------------------------------#include "Font.h"#include "Unichrome.h"#include "Window.h"#include "MemoryBlock.h"#include "util/FileReader.h"#include "util/FileWriter.h"#include "util/Log.h"//------------------------------------------------------------------------------using unichrome::Font;//------------------------------------------------------------------------------Font::Chunk::Chunk(Chunk* next, size_t numChars, size_t width, size_t height) :    next(next),    numChars(numChars),    width(width),    height(height),    location(HOST_MEMORY),    buffer(new unsigned char[width*height]){    memset(buffer, 0, width*height);}        //------------------------------------------------------------------------------Font::Chunk::Chunk(Chunk* next, size_t numChars,                    Unichrome& unichrome,                   FileReader& reader, unsigned /*version*/) :    next(next),    numChars(numChars),    width(reader.read8()),    height(reader.read8()),    location(BOARD_MEMORY){    memoryBlock = unichrome.allocateMemoryBlock(width*height);    reader.read(const_cast<void*>(memoryBlock->getBuffer()), width*height);//     printf("Read chunk of size %ux%u containining %u characters\n",//            width, height, numChars);}//------------------------------------------------------------------------------Font::Chunk::~Chunk(){    switch(location) {      case HOST_MEMORY:        delete[] buffer;        break;      case BOARD_MEMORY:        delete memoryBlock;        break;      default:        assert(0);    }    delete next;}//------------------------------------------------------------------------------volatile unsigned char* Font::Chunk::getBuffer(){    switch(location) {      case HOST_MEMORY:        return buffer;        break;      case BOARD_MEMORY:        return memoryBlock->getBuffer8();        break;      default:        assert(0);    }}//------------------------------------------------------------------------------void Font::Chunk::setSource(){    assert(location==BOARD_MEMORY);    memoryBlock->setSource(width);}//------------------------------------------------------------------------------void Font::Chunk::write(FileWriter& writer){    assert(location==HOST_MEMORY);    writer.write8(numChars);    writer.write8(width);    writer.write8(height);    writer.write(const_cast<unsigned char*>(getBuffer()), width*height);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------Font::Glyph::Glyph(Glyph* next, char code,                   Chunk* chunk, size_t offset,                   size_t width, size_t height,                    ssize_t left, ssize_t top, ssize_t advance) :    next(next),    code(code),    chunk(chunk),    offset(offset),    width(width), height(height),    left(left), top(top), advance(advance){}    //------------------------------------------------------------------------------Font::Glyph::Glyph(Glyph* next, Chunk* chunk,                    FileReader& reader, unsigned /*version*/) :    next(next),    code(reader.readS8()),    chunk(chunk),    offset(reader.read8()),    width(reader.read8()),    height(reader.read8()),    left(reader.readS8()),    top(reader.readS8()),    advance(reader.readS8()){//     printf("Read glyph %04x: offset=%u, width=%u, height=%u, left=%d, top=%d\n",//            code, offset, width, height, left, top);}        //------------------------------------------------------------------------------Font::Glyph::~Glyph(){    delete next;}//------------------------------------------------------------------------------void Font::Glyph::setPixel(size_t x, size_t y, bool bit){    size_t bufferOffset = (offset+x)/8 + y * chunk->width;    size_t bufferShift  = 7 - ( (offset+x)%8 );        if (bit) chunk->getBuffer()[bufferOffset] |= 1<<bufferShift;    else chunk->getBuffer()[bufferOffset] &= ~(1<<bufferShift);}//------------------------------------------------------------------------------size_t Font::Glyph::blit(Window& window,                         size_t x, size_t y, bool transparent){    if (width==0 || height==0) return x;     chunk->setSource();    window.blit(offset, 0,                 width, height,                x + left, y - top,                transparent ?                 Window::BLIT_MONO_TRANSPARENT_COPY :                Window::BLIT_MONO_COPY);        return x + advance;}//------------------------------------------------------------------------------void Font::Glyph::write(FileWriter& writer){    writer.writeS8(code);    writer.write8(offset);    writer.write8(width);    writer.write8(height);    writer.writeS8(left);    writer.writeS8(top);    writer.writeS8(advance);}//------------------------------------------------------------------------------//------------------------------------------------------------------------------const char Font::magic[4] = { 'D', '3', 'P', 'F' };//------------------------------------------------------------------------------inline size_t Font::char2Index(char code){    return static_cast<unsigned char>(code);}//------------------------------------------------------------------------------Font::Font() :    firstChunk(0),    firstGlyph(0),    maxTop(-1000),    maxBottom(1000){    memset(glyphTable, 0, sizeof(glyphTable));}//------------------------------------------------------------------------------Font::Font(Unichrome& unichrome, FILE* file) :     maxTop(-1000),    maxBottom(1000){    init(unichrome, file);}//------------------------------------------------------------------------------Font::Font(Unichrome& unichrome, const char* name, const char* directory) :    maxTop(-1000),    maxBottom(1000){    memset(glyphTable, 0, sizeof(glyphTable));    char fileName[256];    if (directory==0) {         snprintf(fileName, sizeof(fileName), "%s", name);    } else {        snprintf(fileName, sizeof(fileName), "%s/%s", directory, name);    }        FILE* file = fopen(fileName, "rb");    if (file==0) {        Log::fatal("unichrome::Font::Font: cannot open font file %s\n",                   fileName);        abort();    }    init(unichrome, file);    fclose(file);}//------------------------------------------------------------------------------Font::~Font(){    delete firstGlyph;    delete firstChunk;}//------------------------------------------------------------------------------void Font::startChunk(size_t numChars, size_t width, size_t height){    firstChunk = new Chunk(firstChunk, numChars, width, height);}//------------------------------------------------------------------------------void Font::startGlyph(char code, size_t offset,                       size_t width, size_t height,                      ssize_t top, ssize_t left, ssize_t advance) {    assert(firstChunk!=0);    size_t index = char2Index(code);    assert(glyphTable[index]==0);    firstGlyph = new Glyph(firstGlyph, code,                            firstChunk, offset,                           width, height, top, left, advance);    glyphTable[index] = firstGlyph;    if (top>maxTop) maxTop = top;    ssize_t bottom = top - height;    if (bottom<maxBottom) maxBottom = bottom;}//------------------------------------------------------------------------------void Font::setGlyphPixel(size_t x, size_t y, bool bit){    assert(firstGlyph!=0);    firstGlyph->setPixel(x, y, bit);}//------------------------------------------------------------------------------inline Font::Glyph* Font::findGlyph(char code){    return glyphTable[char2Index(code)];}//------------------------------------------------------------------------------size_t Font::displayCharacter(Window& window,                              size_t x, size_t y, char code, bool transparent){    Glyph* glyph = findGlyph(code);    if (glyph==0) return x;    if (code==32 && glyph->width==0) {        glyph = findGlyph('-');        return (glyph==0) ? x+5 : x+glyph->width;    } else return glyph->blit(window, x, y, transparent);}//------------------------------------------------------------------------------size_t Font::displayText(Window& window,                         size_t x, size_t y, const char* text, bool transparent){    while( *text!='\0' ) {        x = displayCharacter(window, x, y, *text, transparent);        ++text;    }    return x;}//------------------------------------------------------------------------------void Font::displayTextAround(Window& window,                             size_t x, size_t y, const char* text,                             bool transparent){    size_t width, height;    ssize_t left, top;    getDimensions(text, width, height, left, top);    x -= width / 2;    y -= height / 2; y += top;        displayText(window, x, y, text, transparent);}//------------------------------------------------------------------------------void Font::getDimensions(const char* text, size_t& width, size_t& height,                         ssize_t& left, ssize_t& top){    width = 0;    height = 0;    left = 0;    top = 0;        ssize_t maxTop = 0;    ssize_t minBottom = 0;    while( *text!='\0' ) {        Glyph* glyph = findGlyph(*text);        if (glyph!=0) {            if (width==0) {                left = glyph->left;            }                        if (*text==' ' && glyph->advance==0) {                glyph = findGlyph('-');                width += (glyph==0) ? 5 : glyph->advance;            } else {                width += glyph->advance;                if (glyph->top > maxTop) {                    maxTop = glyph->top;                }                ssize_t bottom = glyph->top - glyph->height;                if ( bottom<minBottom ) {                    minBottom = bottom;                }            }        }        ++text;    }    top = maxTop;    height = maxTop + 1 - minBottom;}//------------------------------------------------------------------------------size_t Font::getHeight(ssize_t& maxTop, ssize_t& maxBottom, const char* charset){    if (charset==0) {        maxTop = this->maxTop;        maxBottom = this->maxBottom;    } else {        maxTop = -1000;        maxBottom = 1000;        while(*charset!='\0') {            Glyph* glyph = findGlyph(*charset);            if (glyph!=0) {                if (glyph->top>maxTop) maxTop = glyph->top;                ssize_t bottom = glyph->top - glyph->height;                if (bottom<maxBottom) maxBottom = bottom;            }            ++charset;        }    }    return maxTop + 1 - maxBottom;}//------------------------------------------------------------------------------void Font::write(FILE* f){    fwrite(magic, sizeof(magic), 1, f);    FileWriter writer(f);        writer.write32(currentVersion);    Chunk* chunk = firstChunk;    Glyph* glyph = firstGlyph;    while(chunk!=0) {        assert(glyph->chunk==chunk);        chunk->write(writer);        while(glyph!=0 && glyph->chunk==chunk) {            glyph->write(writer);            glyph = glyph->next;        }        chunk=chunk->next;    }    assert(glyph==0);}//------------------------------------------------------------------------------void Font::init(Unichrome& unichrome, FILE* file){    firstChunk = 0;    firstGlyph = 0;    memset(glyphTable, 0, sizeof(glyphTable));    char magicBuffer[sizeof(magic)];    fread(magicBuffer, sizeof(magicBuffer), 1, file);    assert(memcmp(magic, magicBuffer, sizeof(magic))==0);    FileReader reader(file);        unsigned version = reader.read32();    uint8_t numChars;    while(reader.read(numChars)) {        firstChunk = new Chunk(firstChunk, numChars, unichrome,                               reader, version);        for(size_t i = 0; i<numChars; ++i) {            firstGlyph = new Glyph(firstGlyph, firstChunk,                                   reader, version);            size_t index = char2Index(firstGlyph->code);            assert(glyphTable[index]==0);                        glyphTable[index] = firstGlyph;            ssize_t top = firstGlyph->top;            if (top>maxTop) maxTop = top;                        ssize_t bottom = top - firstGlyph->height;            if (bottom<maxBottom) maxBottom = bottom;        }    }}//------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -