/******************************************************************************
*
* Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
*
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* FTPattern.h
*
*****************************************************************************/
#pragma once
#include <oz++/CommonObject.h>
#include <oz++/Exception.h>
#include <oz++/motif/Args.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
#include <string.h>
#include <oz++/xft/FTNames.h>
namespace OZ {
class FTPattern :public CommonObject{
private:
FcPattern* pattern;
bool destructive;
public:
FTPattern()
:pattern(FcPatternCreate()),
destructive(true)
{
if (pattern == NULL) {
throw IException("Failed in FcPatternCreate");
}
}
public:
FTPattern(FcPattern* pat)
:pattern(pat),
destructive(false)
{
if (pattern == NULL) {
throw IException("Invalid argument");
}
}
public:
~FTPattern()
{
if (pattern && destructive) {
FcPatternDestroy(pattern);
}
pattern = NULL;
}
public:
FcPattern* get()
{
return pattern;
}
void addPattern(const char* name, XtArgVal val, XFCTYPE type)
{
switch(type) {
case XFCTYPE_STRING:
add(name, (const char*)val);
break;
case XFCTYPE_INTEGER:
add(name, (int)val);
break;
case XFCTYPE_CHARSET:
add(name, (FcCharSet*)val);
break;
case XFCTYPE_DOUBLE:
add(name, (double)val);
break;
case XFCTYPE_BOOL:
add(name, (FcBool)val);
break;
case XFCTYPE_MATRIX:
add(name, (FcMatrix*)val);
break;
}
}
public:
void add(Args& args)
{
int size = args.count();
ArgList ar = args.getArgList();
FTNames ftNames;
for (int i = 0; i<size; i++) {
const char* name = ar[i].name;
XtArgVal val = ar[i].value;
try {
if (strncmp(name, XftNamePrefix, strlen(XftNamePrefix)) == 0) {
XFCTYPE type = ftNames.getType(name);
const char* fcname = strchr(name, '_');
if (fcname) {
addPattern(++fcname, val, type);
}
}
} catch (...) {
//Ignore an IException
}
}
}
public:
void display()
{
FcPatternPrint(pattern);
}
public:
void add(const char* name, const char* value)
{
FcPatternAddString(pattern, name, (FcChar8*)value);
}
void add(const char* name, int value)
{
FcPatternAddInteger(pattern, name, value);
}
void add(const char* name, double value)
{
FcPatternAddInteger(pattern, name, value);
}
void add(const char* name, FcMatrix* value)
{
FcPatternAddMatrix(pattern, name, value);
}
void add(const char* name, FcCharSet* value)
{
FcPatternAddCharSet(pattern, name, value);
}
void del(const char* name)
{
FcPatternDel(pattern, name);
}
FcPattern* match(Display* display)
{
FcResult result;
int screen = DefaultScreen(display);
FcPattern* matchedPattern = XftFontMatch(display, screen, pattern, &result);
if (result != FcResultMatch) {
throw IException("Failed to XftFontMatch");
}
return matchedPattern;
}
int isEqual(FTPattern* fontPattern)
{
return FcPatternEqual(this -> pattern, fontPattern ->get() );
}
};
}
//
/*
Usage example:
FTPattern* pattern = new FTPattern();
pattern -> add(FC_FMMILIY, "Courier");
pattern -> add(FC_SLANT, FC_SLANT_ITALIC); //FC_SLANT_ROMAN
pattern -> add(FC_SIZE, pointsize);// 12.0
//pattern -> add(FC_PIXEL_SIZE, pixelsize);
pattern -> add(FC_WEIGHT, FC_WEIGHT_BOLD); //FC_WEIGHT_NORMAL
pattern -> add(FC_MINSPACE, 1);
pattern -> add(FC_ANTIALIAS, FcTrue); //FcFalse
*/
//