【问题标题】:Converting truetype font default to pixel size in NV Path在 NV 路径中将 truetype 字体默认转换为像素大小
【发布时间】:2013-04-24 11:39:07
【问题描述】:

我正在使用NVidia Path extension(NV 路径)为 OpenGL 引擎编写文本模块。该扩展允许使用trutype metrics 加载系统和外部字体文件。现在,我需要能够在渲染文本时为字形设置标准字体大小(以像素为单位)。默认情况下,加载的字形具有 EMscale = 2048。搜索字形指标到像素的转换我发现了这个:

将 FUnit 转换为像素

em 方格中的值被转换为像素中的值 坐标系通过将它们乘以比例。这个比例是: pointSize * 分辨率 / (每英寸 72 点 * units_per_em )

所以 units_per_em 等于 2048,pointSize 和分辨率是我无法解决的未知数。如何获得视口宽度和高度的分辨率值以进入这个等式?另外,如果我的输入是字体的像素大小,点大小应该是多少?

我尝试使用不同类型的输入来求解这个方程,但我渲染的文本总是比参考文本 (AfterEffects) 更小(或更大)。

NV_Path 文档参考FreeType2 metrics。参考资料说:

在 face->glyph->metrics 中找到的指标通常用 26.6 像素格式(即 1/64 像素),除非您在调用 FT_Load_Glyph 或 FT_Load_Char 时使用 FT_LOAD_NO_SCALE 标志。在 在这种情况下,指标将以原始字体单位表示。

我尝试将文本模型矩阵缩小 1/64。它接近正确的大小,但仍不完美。

这是我目前在代码中设置文本渲染的方式:

            emScale=2048;

        glyphBase = glGenPathsNV(1+numChars);
    pathTemplate= ~0;
    glPathGlyphRangeNV(glyphBase,GL_SYSTEM_FONT_NAME_NV,
        "Verdana",GL_BOLD_BIT_NV,0,numChars,GL_SKIP_MISSING_GLYPH_NV,pathTemplate,emScale);


    /* Query font and glyph metrics. */
    glGetPathMetricRangeNV(
        GL_FONT_Y_MIN_BOUNDS_BIT_NV|
        GL_FONT_Y_MAX_BOUNDS_BIT_NV|
        GL_FONT_X_MIN_BOUNDS_BIT_NV|
        GL_FONT_X_MAX_BOUNDS_BIT_NV|
        GL_FONT_UNDERLINE_POSITION_BIT_NV|
        GL_FONT_UNDERLINE_THICKNESS_BIT_NV,glyphBase+' ' ,1 ,6*sizeof(GLfloat),font_data);


    glGetPathMetricRangeNV(GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV,
        glyphBase,numChars,0,horizontalAdvance);

    /* Query spacing information for example's message. */

    messageLen = strlen(message);
    xtranslate =(GLfloat*)malloc(sizeof(GLfloat) *messageLen);
    if(!xtranslate){
        fprintf(stderr, "%s: malloc of xtranslate failed\n", "Text3D error");
        exit(1);
    }

    xtranslate[0] = 0.0f;  /* Initial xtranslate is zero. */
    /* Use 100% spacing; use 0.9 for both for 90% spacing. */
    GLfloat advanceScale = 1.0f,
        kerningScale = 1.0f; 

    glGetPathSpacingNV(GL_ACCUM_ADJACENT_PAIRS_NV,
        (GLsizei)messageLen,GL_UNSIGNED_BYTE,message,glyphBase,
        advanceScale,kerningScale,GL_TRANSLATE_X_NV,&xtranslate[1]); /* messageLen-1 accumulated translates are written here. */

    const unsigned char *message_ub = (const unsigned char*)message;
    totalAdvance = xtranslate[messageLen-1] +
        horizontalAdvance[message_ub[messageLen-1]];
    xBorder = totalAdvance / messageLen;

    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_NOTEQUAL ,0 ,~0);
    glStencilOp(GL_KEEP,GL_KEEP,GL_ZERO);


    ////////// init matrices  /////////////

    translate(model ,vec3(0));
    translate(view  ,vec3(0));

                    float nearF=1 ,farF = 1200;
            glViewport(0,0,_viewPortW,_viewPortH);
        glMatrixLoadIdentityEXT(GL_PROJECTION);


        float aspect_ratio =(float) _viewPortW /(float) _viewPortH;
        glMatrixFrustumEXT(GL_PROJECTION ,-aspect_ratio,aspect_ratio,-1 ,1 ,nearF,farF);





        model=translate(model,vec3(0.0f,384.0,0.0f));//move up
            //scale by 26.6 also doesn't work:
    model=scale(model,vec3((1.0f/26.6f),1.0f/26.6f,1.0f/26.6f));
    view=lookAt(vec3(0,0,0),vec3(0,0,-1),vec3(0,1,0));

}

【问题讨论】:

    标签: opengl fonts truetype freetype


    【解决方案1】:

    分辨率取决于设备并使用 DPI(每英寸点数)给出的公式。 point_size 是字体的大小,由用户在 Points 中选择。 A Point = 1/72 英寸(实际上这是 PostScript 中使用的 Point 的大小,排字机使用的实际单位“Point”略有不同)。

    可以使用操作系统相关的方法查询设备分辨率。谷歌“显示 DPI $NAMEOFOPERATINGSYSTEM”。使用以磅为单位的大小可以为您提供与使用的显示设备无关的恒定物理字体大小。

    请注意,当使用 OpenGL 进行渲染时,您仍会经历必须考虑的转换管道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      • 2013-06-13
      • 2020-11-02
      • 2013-07-07
      • 2013-05-06
      • 1970-01-01
      相关资源
      最近更新 更多