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

Java example source code file (X11FontScaler_md.c)

This example Java source code file (X11FontScaler_md.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

awt_unlock, awtchar, awtchar2b, badalloc, font_awt_lock, headless, jnicall, jnienv, jniexport, msbfirst, null, xcharstruct, xfontstruct, xsetforeground

The X11FontScaler_md.c Java example source code

/*
 * Copyright (c) 2001, 2003, 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.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <ctype.h>
#include <sys/utsname.h>

#include <jni.h>
#include <jni_util.h>
#include "fontscalerdefs.h"
#include "X11FontScaler.h"

#ifndef HEADLESS

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <awt.h>

static GC pixmapGC = 0;
static Pixmap pixmap = 0;
static Atom psAtom = 0;
static Atom fullNameAtom = 0;
static int pixmapWidth = 0;
static int pixmapHeight = 0;

#define FONT_AWT_LOCK() \
env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); \
AWT_LOCK();

int CreatePixmapAndGC (int width, int height)
{
    /* REMIND: use the actual screen, not the default screen */
    Window awt_defaultRoot =
        RootWindow(awt_display, DefaultScreen(awt_display));

    if (width < 100) {
      width = 100;
    }
    if (height < 100) {
      height = 100;
    }
    pixmapHeight = height;
    pixmapWidth = width;
    if (pixmap != 0) {
      XFreePixmap (awt_display, pixmap);
    }
    if (pixmapGC != NULL) {
      XFreeGC (awt_display, pixmapGC);
    }
    pixmap = XCreatePixmap (awt_display, awt_defaultRoot, pixmapWidth,
                          pixmapHeight, 1);
    if (pixmap == 0) {
      return BadAlloc;
    }
    pixmapGC = XCreateGC (awt_display, pixmap, 0, 0);
    if (pixmapGC == NULL) {
      return BadAlloc;
    }
    XFillRectangle (awt_display, pixmap, pixmapGC, 0, 0, pixmapWidth,
                  pixmapHeight);
    XSetForeground (awt_display, pixmapGC, 1);
    return Success;
}

#ifdef DUMP_IMAGES

static void dumpXImage(XImage *ximage)
{
    int height = ximage->height;
    int width = ximage->width;
    int row;
    int column;

    fprintf(stderr, "-------------------------------------------\n");
    for (row = 0; row < height; ++row) {
      for (column = 0; column < width; ++column) {
          int pixel = ximage->f.get_pixel(ximage, column, row);
          fprintf(stderr, (pixel == 0) ? "  " : "XX");
      }
      fprintf(stderr, "\n");
    }
    fprintf(stderr, "-------------------------------------------\n");
}

#endif

#endif /* !HEADLESS */

JNIEXPORT int JNICALL AWTCountFonts(char* xlfd) {
#ifdef HEADLESS
    return 0;
#else
    char **names;
    int count;
    JNIEnv *env;
    FONT_AWT_LOCK();
    names = XListFonts(awt_display, xlfd, 3, &count);
    XFreeFontNames(names);
    AWT_UNLOCK();
    return count;
#endif /* !HEADLESS */
}

JNIEXPORT void JNICALL AWTLoadFont(char* name, AWTFont *pReturn) {
    JNIEnv *env;
    *pReturn = NULL;
#ifndef HEADLESS
    FONT_AWT_LOCK();
    *pReturn = (AWTFont)XLoadQueryFont(awt_display, name);
    AWT_UNLOCK();
#endif /* !HEADLESS */
}

JNIEXPORT void JNICALL AWTFreeFont(AWTFont font) {
#ifndef HEADLESS
    JNIEnv *env;
    FONT_AWT_LOCK();
    XFreeFont(awt_display, (XFontStruct *)font);
    AWT_UNLOCK();
#endif /* !HEADLESS */
}

JNIEXPORT unsigned JNICALL AWTFontMinByte1(AWTFont font) {
#ifdef HEADLESS
    return 0;
#else
    return ((XFontStruct *)font)->min_byte1;
#endif /* !HEADLESS */
}

JNIEXPORT unsigned JNICALL AWTFontMaxByte1(AWTFont font) {
#ifdef HEADLESS
    return 0;
#else
    return ((XFontStruct *)font)->max_byte1;
#endif /* !HEADLESS */
}

JNIEXPORT unsigned JNICALL AWTFontMinCharOrByte2(AWTFont font) {
#ifdef HEADLESS
    return 0;
#else
    return ((XFontStruct *)font)->min_char_or_byte2;
#endif /* !HEADLESS */
}

JNIEXPORT unsigned JNICALL AWTFontMaxCharOrByte2(AWTFont font) {
#ifdef HEADLESS
    return 0;
#else
    return ((XFontStruct *)font)->max_char_or_byte2;
#endif /* !HEADLESS */
}

JNIEXPORT unsigned JNICALL AWTFontDefaultChar(AWTFont font) {
#ifdef HEADLESS
    return 0;
#else
    return ((XFontStruct *)font)->default_char;
#endif /* !HEADLESS */
}

JNIEXPORT AWTChar JNICALL AWTFontPerChar(AWTFont font, int index) {
#ifdef HEADLESS
    return NULL;
#else
    XFontStruct *fXFont = (XFontStruct *)font;
    XCharStruct *perChar = fXFont->per_char;
    if (perChar == NULL) {
        return NULL;
    }
    return (AWTChar)&(perChar[index]);
#endif /* !HEADLESS */
}

JNIEXPORT AWTChar JNICALL AWTFontMaxBounds(AWTFont font) {
#ifdef HEADLESS
    return 0;
#else
    return (AWTChar)&((XFontStruct *)font)->max_bounds;
#endif /* !HEADLESS */
}


JNIEXPORT int JNICALL AWTFontAscent(AWTFont font) {
#ifdef HEADLESS
    return 0;
#else
    return ((XFontStruct *)font)->ascent;
#endif /* !HEADLESS */
}


JNIEXPORT int JNICALL AWTFontDescent(AWTFont font) {
#ifdef HEADLESS
    return 0;
#else
    return ((XFontStruct *)font)->descent;
#endif /* !HEADLESS */
}

JNIEXPORT void JNICALL AWTFontTextExtents16(AWTFont font,
                                            AWTChar2b* xChar,
                                            AWTChar* overall) {
#ifndef HEADLESS
    JNIEnv *env;
    int ascent, descent, direction;
    XFontStruct* xFont = (XFontStruct*)font;
    XCharStruct* newChar = (XCharStruct*)malloc(sizeof(XCharStruct));
    *overall = (AWTChar)newChar;
    /* There is a claim from the pre 1.5 source base that the info in the
     * XFontStruct is flaky for 16 byte chars. This seems plausible as
     * for info to be valid, that struct would need a large number of
     * XCharStructs. But there's nothing in the X APIs which warns you of
     * this. If it really is flaky you must question why there's an
     * XTextExtents16 API call. Try XTextExtents16 for now and if it fails
     * go back to XQueryTextExtents16 in this function.
     * Indeed the metrics from the Solaris 9 JA font
     * -ricoh-gothic-medium-r-normal--*-140-72-72-m-*-jisx0208.1983-0
     * do appear different so revert to the query api
     */
    FONT_AWT_LOCK();
    XQueryTextExtents16(awt_display,xFont->fid, xChar, 1,
                        &direction, &ascent, &descent, newChar);
/* XTextExtents16(xFont, xChar, 1, &direction, &ascent, &descent, newChar);  */
    AWT_UNLOCK();
#endif /* !HEADLESS */
}

JNIEXPORT void JNICALL AWTFreeChar(AWTChar xChar) {
#ifndef HEADLESS
    free(xChar);
#endif /* !HEADLESS */
}

JNIEXPORT jlong JNICALL AWTFontGenerateImage(AWTFont pFont, AWTChar2b* xChar) {

#ifndef HEADLESS

    int width, height, direction, ascent, descent;
    GlyphInfo *glyphInfo;
    XFontStruct* xFont = (XFontStruct*)pFont;
    XCharStruct xcs;
    XImage *ximage;
    int h, i, j, nbytes;
    unsigned char *srcRow, *dstRow, *dstByte;
    int wholeByteCount, remainingBitsCount;
    unsigned int imageSize;
    JNIEnv *env;

    FONT_AWT_LOCK();
/*     XTextExtents16(xFont, xChar, 1, &direction, &ascent, &descent, &xcs); */
    XQueryTextExtents16(awt_display,xFont->fid, xChar, 1,
                        &direction, &ascent, &descent, &xcs);
    width = xcs.rbearing - xcs.lbearing;
    height = xcs.ascent+xcs.descent;
    imageSize = width*height;

    glyphInfo = (GlyphInfo*)malloc(sizeof(GlyphInfo)+imageSize);
    glyphInfo->cellInfo = NULL;
    glyphInfo->width = width;
    glyphInfo->height = height;
    glyphInfo->topLeftX = xcs.lbearing;
    glyphInfo->topLeftY = -xcs.ascent;
    glyphInfo->advanceX = xcs.width;
    glyphInfo->advanceY = 0;

    if (imageSize == 0) {
        glyphInfo->image = NULL;
        AWT_UNLOCK();
        return (jlong)(uintptr_t)glyphInfo;
    } else {
        glyphInfo->image = (unsigned char*)glyphInfo+sizeof(GlyphInfo);
    }

    if ((pixmap == 0) || (width > pixmapWidth) || (height > pixmapHeight)) {
        if (CreatePixmapAndGC(width, height) != Success) {
            glyphInfo->image = NULL;
            AWT_UNLOCK();
            return (jlong)(uintptr_t)glyphInfo;
        }
    }

    XSetFont(awt_display, pixmapGC, xFont->fid);
    XSetForeground(awt_display, pixmapGC, 0);
    XFillRectangle(awt_display, pixmap, pixmapGC, 0, 0,
                   pixmapWidth, pixmapHeight);
    XSetForeground(awt_display, pixmapGC, 1);
    XDrawString16(awt_display, pixmap, pixmapGC,
                  -xcs.lbearing, xcs.ascent, xChar, 1);
    ximage = XGetImage(awt_display, pixmap, 0, 0, width, height,
                       AllPlanes, XYPixmap);

    if (ximage == NULL) {
        glyphInfo->image = NULL;
        AWT_UNLOCK();
        return (jlong)(uintptr_t)glyphInfo;
    }

#ifdef DUMP_IMAGES
    dumpXImage(ximage);
#endif

    nbytes =  ximage->bytes_per_line;
    srcRow = (unsigned char*)ximage->data;
    dstRow = (unsigned char*)glyphInfo->image;
    wholeByteCount = width >> 3;
    remainingBitsCount = width & 7;

    for (h=0; h<height; h++) {
        const UInt8* src8 = srcRow;
        UInt8 *dstByte = dstRow;
        UInt32 srcValue;

        srcRow += nbytes;
        dstRow += width;

        for (i = 0; i < wholeByteCount; i++) {
            srcValue = *src8++;
            for (j = 0; j < 8; j++) {
                if (ximage->bitmap_bit_order == LSBFirst) {
                    *dstByte++ = (srcValue & 0x01) ? 0xFF : 0;
                    srcValue >>= 1;
                } else {                /* MSBFirst */
                    *dstByte++ = (srcValue & 0x80) ? 0xFF : 0;
                    srcValue <<= 1;
                }
            }
        }
        if (remainingBitsCount) {
            srcValue = *src8;
            for (j = 0; j < remainingBitsCount; j++) {
                if (ximage->bitmap_bit_order == LSBFirst) {
                    *dstByte++ = (srcValue & 0x01) ? 0xFF : 0;
                    srcValue >>= 1;
                } else {                /* MSBFirst */
                    *dstByte++ = (srcValue & 0x80) ? 0xFF : 0;
                    srcValue <<= 1;
                }
            }
        }
    }

    XDestroyImage (ximage);
    AWT_UNLOCK();
    return (jlong)(uintptr_t)glyphInfo;
#else
    return (jlong)0;
#endif /* !HEADLESS */
}

JNIEXPORT short JNICALL AWTCharAdvance(AWTChar xChar) {
#ifdef HEADLESS
    return 0;
#else
    return ((XCharStruct *)xChar)->width;
#endif /* !HEADLESS */
}

JNIEXPORT short JNICALL AWTCharLBearing(AWTChar xChar) {
#ifdef HEADLESS
    return 0;
#else
    return ((XCharStruct *)xChar)->lbearing;
#endif /* !HEADLESS */
}

JNIEXPORT short JNICALL AWTCharRBearing(AWTChar xChar) {
#ifdef HEADLESS
    return 0;
#else
    return ((XCharStruct *)xChar)->rbearing;
#endif /* !HEADLESS */
}

JNIEXPORT short JNICALL AWTCharAscent(AWTChar xChar) {
#ifdef HEADLESS
    return 0;
#else
    return ((XCharStruct *)xChar)->ascent;
#endif /* !HEADLESS */
}

JNIEXPORT short JNICALL AWTCharDescent(AWTChar xChar) {
#ifdef HEADLESS
    return 0;
#else
    return ((XCharStruct *)xChar)->descent;
#endif /* !HEADLESS */
}

Other Java examples (source code examples)

Here is a short list of links related to this Java X11FontScaler_md.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.