alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (X11FontScaler.c)

This example Java source code file (X11FontScaler.c) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

awtchar2b, awtcharadvance, awtfont, awtfontgenerateimage, java_sun_font_nativestrike_createscalercontext, jni_false, jni_true, jnicall, jnienv, jniexport, nativescalercontext, nativescalercontext\*, no_pointsize, null

The X11FontScaler.c Java example source code

/*
 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * Important note : All AWTxxx functions are defined in font.h.
 * These were added to remove the dependency of this file on X11.
 * These functions are used to perform X11 operations and should
 * be "stubbed out" in environments that do not support X11.
 * The implementation of these functions has been moved from this file
 * into X11FontScaler_md.c, which is compiled into another library.
 */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/utsname.h>

#include <jni.h>
#include <jni_util.h>

#include "sun_font_NativeFont.h"
#include "sun_font_NativeStrike.h"
#include "sun_font_NativeStrikeDisposer.h"
#include "sunfontids.h"
#include "fontscalerdefs.h"
#include "X11FontScaler.h"

JNIEXPORT void JNICALL
    Java_sun_font_NativeStrikeDisposer_freeNativeScalerContext
    (JNIEnv *env, jobject disposer, jlong pScalerContext) {

    NativeScalerContext *context = (NativeScalerContext*)pScalerContext;

    if (context != NULL) {
        if (context->xFont != NULL) {
            AWTFreeFont(context->xFont);
        }
        free(context);
    }
}

JNIEXPORT jlong JNICALL
Java_sun_font_NativeStrike_createNullScalerContext
    (JNIEnv *env, jobject strike) {

   NativeScalerContext *context =
       (NativeScalerContext*)malloc(sizeof(NativeScalerContext));
   context->xFont = NULL;
   context->minGlyph = 0;
   context->maxGlyph = 0;
   context->numGlyphs = 0;
   context->defaultGlyph = 0;
   context->ptSize = NO_POINTSIZE;
   return (jlong)(uintptr_t)context;
}

JNIEXPORT jlong JNICALL
Java_sun_font_NativeStrike_createScalerContext
    (JNIEnv *env, jobject strike, jbyteArray xlfdBytes,
     jint ptSize, jdouble scale) {

    NativeScalerContext *context;
    int len = (*env)->GetArrayLength(env, xlfdBytes);

    char* xlfd = (char*)malloc(len+1);

    if (xlfd == NULL) {
        return (jlong)(uintptr_t)0L;
    }

    (*env)->GetByteArrayRegion(env, xlfdBytes, 0, len, (jbyte*)xlfd);
    xlfd[len] = '\0';
    context = (NativeScalerContext*)malloc(sizeof(NativeScalerContext));

    AWTLoadFont (xlfd, &(context->xFont));
    free(xlfd);

    if (context->xFont == NULL) {   /* NULL means couldn't find the font */
        free(context);
        context = NULL;
    } else {
        /* numGlyphs is an estimate : X11 doesn't provide a quick way to
         * discover which glyphs are valid: just the range that contains all
         * the valid glyphs, and this range may have holes.
         */
        context->minGlyph = (AWTFontMinByte1(context->xFont) << 8) +
            AWTFontMinCharOrByte2(context->xFont);
        context->maxGlyph = (AWTFontMaxByte1(context->xFont) << 8) +
            AWTFontMaxCharOrByte2(context->xFont);
        context->numGlyphs = context->maxGlyph - context->minGlyph + 1;
        context->defaultGlyph = AWTFontDefaultChar(context->xFont);
        /* Sometimes the default_char field of the XFontStruct isn't
         * initialized to anything, so it can be a large number. So,
         * check to see if its less than the largest possible value
         * and if so, then use it. Otherwise, just use the minGlyph.
         */
        if (context->defaultGlyph < context->minGlyph ||
            context->defaultGlyph > context->maxGlyph) {
            context->defaultGlyph = context->minGlyph;
        }
        context->ptSize = ptSize;
        context->scale = scale;
    }

    /*
     * REMIND: freeing of native resources? XID, XFontStruct etc??
     */
    return (jlong)(uintptr_t)context;
}


/* JNIEXPORT jint JNICALL */
/* Java_sun_font_NativeFont_getItalicAngle */
/*     (JNIEnv *env, jobject font) { */

/*     UInt32 angle; */
/*     AWTGetFontItalicAngle(xFont, &angle); */
/*X11 reports italic angle as 1/64ths of a degree, relative to 3 o'clock
 * with anti-clockwise being the +ve rotation direction.
 * We return
XGetFontProperty(xFont,XA_ITALIC_ANGLE, &angle);
*/

/*     return (jint)angle; */
/* } */

JNIEXPORT jboolean JNICALL
Java_sun_font_NativeFont_fontExists
    (JNIEnv *env, jclass fontClass, jbyteArray xlfdBytes) {

    int count = 0;
    int len = (*env)->GetArrayLength(env, xlfdBytes);
    char* xlfd = (char*)malloc(len+1);

    if (xlfd == NULL) {
        return JNI_FALSE;
    }

    (*env)->GetByteArrayRegion(env, xlfdBytes, 0, len, (jbyte*)xlfd);
    xlfd[len] = '\0';

    count = AWTCountFonts(xlfd);
    free(xlfd);
    if (count > 0) {
        return JNI_TRUE;
    } else {
        return JNI_FALSE;
    }
}

JNIEXPORT jboolean JNICALL
Java_sun_font_NativeFont_haveBitmapFonts
    (JNIEnv *env, jclass fontClass, jbyteArray xlfdBytes) {

    int count = 0;
    int len = (*env)->GetArrayLength(env, xlfdBytes);
    char* xlfd = (char*)malloc(len+1);

    if (xlfd == NULL) {
        return JNI_FALSE;
    }

    (*env)->GetByteArrayRegion(env, xlfdBytes, 0, len, (jbyte*)xlfd);
    xlfd[len] = '\0';

    count = AWTCountFonts(xlfd);
    free(xlfd);
    if (count > 2) {
        return JNI_TRUE;
    } else {
        return JNI_FALSE;
    }
}

// CountGlyphs doubles as way of getting a native font reference
// and telling if its valid. So far as I can tell GenerateImage etc
// just return if this "initialisation method" hasn't been called.
// So clients of this class need to call CountGlyphs() right after
// construction to be safe.
JNIEXPORT jint JNICALL
Java_sun_font_NativeFont_countGlyphs
    (JNIEnv *env, jobject font, jbyteArray xlfdBytes, jint ptSize) {

    NativeScalerContext *context = (NativeScalerContext*)
        Java_sun_font_NativeStrike_createScalerContext
        (env, NULL, xlfdBytes, ptSize, 1);

    if (context == NULL) {
        return 0;
    } else {
        int numGlyphs = context->numGlyphs;
        AWTFreeFont(context->xFont);
        free(context);
        return numGlyphs;
    }
}

JNIEXPORT jint JNICALL
Java_sun_font_NativeStrike_getMaxGlyph
    (JNIEnv *env, jobject strike, jlong pScalerContext) {

    NativeScalerContext *context = (NativeScalerContext*)pScalerContext;
    if (context == NULL) {
        return (jint)0;
    } else {
        return (jint)context->maxGlyph+1;
    }
}

JNIEXPORT jfloat JNICALL
Java_sun_font_NativeFont_getGlyphAdvance
   (JNIEnv *env, jobject font2D, jlong pScalerContext, jint glyphCode) {

    NativeScalerContext *context = (NativeScalerContext*)pScalerContext;
    AWTFont xFont = (AWTFont)context->xFont;
    AWTChar xcs;
    jfloat advance = 0.0f;

    if (xFont == NULL || context->ptSize == NO_POINTSIZE) {
        return advance;
    }

    if (glyphCode < context->minGlyph || glyphCode > context->maxGlyph) {
        glyphCode = context->defaultGlyph;
    }

    /* If number of glyphs is 256 or less, the metrics are
     * stored correctly in the XFontStruct for each
     * character. If the # characters is more (double byte
     * case), then these metrics seem flaky and there's no
     * way to determine if they have been set or not.
     */
    if ((context->maxGlyph <= 256) && (AWTFontPerChar(xFont, 0) != NULL)) {
        xcs = AWTFontPerChar(xFont, glyphCode - context->minGlyph);
        advance = AWTCharAdvance(xcs);
    } else {
        int direction, ascent, descent;
        AWTChar2b xChar;

        xChar.byte1 = (unsigned char) (glyphCode >> 8);
        xChar.byte2 = (unsigned char) glyphCode;
        AWTFontTextExtents16(xFont, &xChar, &xcs);
        advance = AWTCharAdvance(xcs);
        AWTFreeChar(xcs);
    }
    return (jfloat)(advance/context->scale);
}

JNIEXPORT jlong JNICALL
Java_sun_font_NativeFont_getGlyphImageNoDefault
    (JNIEnv *env, jobject font2D, jlong pScalerContext, jint glyphCode) {

    NativeScalerContext *context = (NativeScalerContext*)pScalerContext;
    AWTFont xFont = context->xFont;
    AWTChar2b xChar;

    if (xFont == NULL || context->ptSize == NO_POINTSIZE) {
        return (jlong)0;
    }

    if (glyphCode < context->minGlyph || glyphCode > context->maxGlyph) {
        return (jlong)0;
    }

    xChar.byte1 = (unsigned char)(glyphCode >> 8);
    xChar.byte2 = (unsigned char)glyphCode;
    return AWTFontGenerateImage(xFont, &xChar);
}

JNIEXPORT jlong JNICALL
Java_sun_font_NativeFont_getGlyphImage
    (JNIEnv *env, jobject font2D, jlong pScalerContext, jint glyphCode) {

    NativeScalerContext *context = (NativeScalerContext*)pScalerContext;
    AWTFont xFont = context->xFont;
    AWTChar2b xChar;

    if (xFont == NULL || context->ptSize == NO_POINTSIZE) {
        return (jlong)0;
    }

    if (glyphCode < context->minGlyph || glyphCode > context->maxGlyph) {
        glyphCode = context->defaultGlyph;
    }

    xChar.byte1 = (unsigned char)(glyphCode >> 8);
    xChar.byte2 = (unsigned char)glyphCode;
    return AWTFontGenerateImage(xFont, &xChar);
}

JNIEXPORT jobject JNICALL
  Java_sun_font_NativeFont_getFontMetrics
    (JNIEnv *env, jobject font2D, jlong pScalerContext) {

    NativeScalerContext *context = (NativeScalerContext*)pScalerContext;
    AWTFont xFont = (AWTFont)context->xFont;
    jfloat j0=0, j1=1, ay=j0, dy=j0, mx=j0;
    jobject metrics;

    if (xFont == NULL) {
        return NULL;
    }

    /* the commented out lines are the old 1.4.x behaviour which used max
     * bounds instead of the font's designed ascent/descent */
/*   ay =  (jfloat)-AWTCharAscent(AWTFontMaxBounds(xFont)); */
/*   dy =  (jfloat)AWTCharDescent(AWTFontMaxBounds(xFont)); */

    ay = (jfloat)-AWTFontAscent(xFont);
    dy = (jfloat)AWTFontDescent(xFont);
    mx = (jfloat)AWTCharAdvance(AWTFontMaxBounds(xFont));

    /* ascent : no need to set ascentX - it will be zero
     * descent : no need to set descentX - it will be zero
     * baseline :  old releases "made up" a number and also seemed to
     * make it up for "X" and set "Y" to 0.
     * leadingX : no need to set leadingX - it will be zero.
     * leadingY : made-up number, but being compatible with what 1.4.x did
     * advance : no need to set yMaxLinearAdvanceWidth - it will be zero.
     */
    metrics = (*env)->NewObject(env, sunFontIDs.strikeMetricsClass,
                                sunFontIDs.strikeMetricsCtr,
                                j0, ay, j0, dy, j1, j0, j0, j1, mx, j0);
/*      printf("X11 asc=%f dsc=%f adv=%f scale=%f\n", */
/*          ay, dy, mx, (float)context->scale); */
    return metrics;
}

Other Java examples (source code examples)

Here is a short list of links related to this Java X11FontScaler.c source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.