全网首发:JDK绘制文字:四、绘制文字的具体函数分析

简介: 全网首发:JDK绘制文字:四、绘制文字的具体函数分析

经历过一番分析,我们对绘制的相关工作大体了解了。现在要问:具体绘制函数是哪个?代码内容是怎样的?


预备知识

 绘制文字,说到底就是把字体文件中对应的图像数据画上去(代码上就是复制到某个缓冲区)。


 图像,包含几个关键信息:图像宽和高,格式(每个像素是bit,还是byte)。结合宽和格式,就产生了一个每行几个字节的信息。


ByteBinary1Bit.c

DEFINE_BYTE_BINARY_SOLID_DRAWGLYPHLIST(ByteBinary1Bit)

DEFINE_BYTE_BINARY_SOLID_DRAWGLYPHLIST(AnyByteBinary.h)

在LoopMacros.h中有一个类似的DEFINE_SOLID_DRAWGLYPHLIST宏定义。二者几乎一样。


#define DEFINE_BYTE_BINARY_SOLID_DRAWGLYPHLIST(DST) \
void NAME_SOLID_DRAWGLYPHLIST(DST)(SurfaceDataRasInfo *pRasInfo, \
                                   ImageRef *glyphs, \
                                   jint totalGlyphs, jint fgpixel, \
                                   jint argbcolor, \
                                   jint clipLeft, jint clipTop, \
                                   jint clipRight, jint clipBottom, \
                                   NativePrimitive *pPrim, \
                                   CompositeInfo *pCompInfo) \
{ \
    jint glyphCounter; \
    jint scan = pRasInfo->scanStride; \
    DST ## DataType *pPix; \
\
    //totalGlyphs: 本次绘制几个文字
    for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) { \
        DeclareDrawGlyphListClipVars(pixels, rowBytes, width, height, \
                                     left, top, right, bottom) \
        ClipDrawGlyphList(DST, pixels, 1, rowBytes, width, height, \
                          left, top, right, bottom, \
                          clipLeft, clipTop, clipRight, clipBottom, \
                          glyphs, glyphCounter, continue) \
        pPix = PtrCoord(pRasInfo->rasBase,left,DST ## PixelStride,top,scan); \
\
        do { \
            Declare ## DST ## InitialLoadVars(pRasInfo, pPix, DstPix, left) \
            jint x = 0; \
            do { \
                InitialLoad ## DST(pPix, DstPix); \
                if (pixels[x]) { \
                    Store ## DST ## PixelData(pPix, 0, fgpixel, DstPix); \
                } \
                ShiftBits ## DST(DstPix); \
            } while (++x < width); \
            FinalStore ## DST(pPix, DstPix); \
            pPix = PtrAddBytes(pPix, scan); \
            // rowBytes就是每行几个字节
            pixels += rowBytes; \
        } while (--height > 0); \
    } \
}

终于,我们找到了真正的绘制函数。


DeclareDrawGlyphListClipVars(LoopMacros.h)

声明一些局部变量。


#define DeclareDrawGlyphListClipVars(PIXELS, ROWBYTES, WIDTH, HEIGHT, \
                                     LEFT, TOP, RIGHT, BOTTOM) \
    const jubyte * PIXELS; \
    int ROWBYTES; \
    int LEFT, TOP; \
    int WIDTH, HEIGHT; \
    int RIGHT, BOTTOM;
ClipDrawGlyphList(LoopMacros.h)

初始化声明的局部变量。这里可以看到width/height是如何初始化的。


#define ClipDrawGlyphList(DST, PIXELS, BYTESPERPIXEL, ROWBYTES, WIDTH, HEIGHT,\
                          LEFT, TOP, RIGHT, BOTTOM, \
                          CLIPLEFT, CLIPTOP, CLIPRIGHT, CLIPBOTTOM, \
                          GLYPHS, GLYPHCOUNTER, NULLGLYPHCODE) \
    PIXELS = (const jubyte *)GLYPHS[GLYPHCOUNTER].pixels; \
    if (!PIXELS) { \
        NULLGLYPHCODE; \
    } \
    ROWBYTES = GLYPHS[GLYPHCOUNTER].rowBytes; \
    LEFT     = GLYPHS[GLYPHCOUNTER].x; \
    TOP      = GLYPHS[GLYPHCOUNTER].y; \
    WIDTH    = GLYPHS[GLYPHCOUNTER].width; \
    HEIGHT   = GLYPHS[GLYPHCOUNTER].height; \
\
    /* if any clipping required, modify parameters now */ \
    RIGHT  = LEFT + WIDTH; \
    BOTTOM = TOP + HEIGHT; \
    if (LEFT < CLIPLEFT) { \
    /* Multiply needed for LCD text as PIXELS is really BYTES */ \
        PIXELS += (CLIPLEFT - LEFT) * BYTESPERPIXEL ; \
        LEFT = CLIPLEFT; \
    } \
    if (TOP < CLIPTOP) { \
        PIXELS += (CLIPTOP - TOP) * ROWBYTES; \
        TOP = CLIPTOP; \
    } \
    if (RIGHT > CLIPRIGHT) { \
        RIGHT = CLIPRIGHT; \
    } \
    if (BOTTOM > CLIPBOTTOM) { \
        BOTTOM = CLIPBOTTOM; \
    } \
    if (RIGHT <= LEFT || BOTTOM <= TOP) { \
        NULLGLYPHCODE; \
    } \
    WIDTH = RIGHT - LEFT; \
    HEIGHT = BOTTOM - TOP;


看到这里,我们不禁要问:字体的位图信息,是怎么来的呢?

目录
相关文章
|
缓存 Java 数据库连接
分析JDK动态代理的实现
分析JDK动态代理的实现
72 0
|
3月前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
32 1
|
6月前
|
监控 算法 Java
怎么用JDK自带工具进行JVM内存分析
JVM内存分析工具,如`jps`、`jcmd`、`jstat`、`jstack`和`jmap`,是诊断和优化Java应用的关键工具。`jps`列出Java进程,`jcmd`执行诊断任务,如查看JVM参数和线程堆栈,`jstat`监控内存和GC,`jstack`生成线程堆栈信息,而`jmap`则用于生成堆转储文件。这些工具帮助排查内存泄漏、优化内存配置、性能调优和异常分析。例如,`jmap -dump:file=heapdump.hprof &lt;PID&gt;`生成堆转储文件,之后可以用Eclipse Memory Analyzer (MAT)等工具分析。
|
7月前
|
Java
JDK 1.8 函数接口(收藏用)
JDK 1.8 函数接口(收藏用)
|
存储 监控 Java
JDK10优化了哪些功能以及新增了哪些特性功能|JDK各个版本的特性分析
JDK10优化了哪些功能以及新增了哪些特性功能|JDK各个版本的特性分析
|
编解码 移动开发 Java
JDK9优化了哪些功能以及新增了哪些特性功能|JDK各个版本的特性分析
JDK9优化了哪些功能以及新增了哪些特性功能|JDK各个版本的特性分析
|
Cloud Native Java API
JDK 21的新特性总结和分析
JDK 21的新特性总结和分析
361 0
|
缓存 监控 druid
JDK中「SPI」原理分析
JDK中「SPI」原理分析SPI是JDK内置的服务提供加载机制,可以为服务接口加载实现类,解耦是其核心思想,也是很多框架和组件的常用手段;
122 0
JDK中「SPI」原理分析
JDK各个版本的特性分析|JDK7|JDK8|JDK9|JDK10|JDK11|JDK12|JDK13特性分析
JDK各个版本的特性分析|JDK7|JDK8|JDK9|JDK10|JDK11|JDK12|JDK13特性分析
|
消息中间件 存储 Arthas
MQ-消息堆积-JDK Bug导致线程阻塞案例分析
一个JDK BUG导致系统LOAD高的案例分析
191 0