blob: 5d9645934b53c12db8cc552c3e3f38783d9673ee [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "CSSProperties.h"
#include "CSS.h"
#include "DFString.h"
#include "DFHashTable.h"
#include "DFCommon.h"
#include "DFPlatform.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *CSSPropertiesCopyDescription(CSSProperties *properties)
{
DFHashTable *collapsed = CSSCollapseProperties(properties);
char *result = CSSSerializeProperties(collapsed);
DFHashTableRelease(collapsed);
return result;
}
const char **CSSPropertiesCopyNames(CSSProperties *properties)
{
return DFHashTableCopyKeys(properties->hashTable);
}
int CSSPropertiesIsEmpty(CSSProperties *properties)
{
return (DFHashTableCount(properties->hashTable) == 0);
}
const char *CSSGet(CSSProperties *properties, const char *name)
{
if (properties == NULL)
return NULL;
assert(properties->retainCount > 0);
return DFHashTableLookup(properties->hashTable,name);
}
void CSSPut(CSSProperties *properties, const char *name, const char *value)
{
if (properties == NULL)
return;
assert(properties->retainCount > 0);
if (value == NULL)
DFHashTableRemove(properties->hashTable,name);
else
DFHashTableAdd(properties->hashTable,name,(void *)value);
if (!properties->dirty) // Minimise KVO notifications
properties->dirty = 1;
DFCallbackInvoke(properties->changeCallbacks,properties,NULL);
}
void CSSPropertiesUpdateFromRaw(CSSProperties *properties, DFHashTable *raw)
{
DFHashTableRelease(properties->hashTable);
properties->hashTable = DFHashTableCopy(raw);
CSSExpandProperties(properties->hashTable);
if (!properties->dirty) // Minimise KVO notifications
properties->dirty = 1;
DFCallbackInvoke(properties->changeCallbacks,properties,NULL);
}
int CSSGetBold(CSSProperties *properties)
{
return DFStringEquals(CSSGet(properties,"font-weight"),"bold");
}
int CSSGetItalic(CSSProperties *properties)
{
return DFStringEquals(CSSGet(properties,"font-style"),"italic");
}
int CSSGetUnderline(CSSProperties *properties)
{
return (CSSGet(properties,"text-decoration-underline") != NULL);
}
int CSSGetLinethrough(CSSProperties *properties)
{
return (CSSGet(properties,"text-decoration-line-through") != NULL);
}
int CSSGetOverline(CSSProperties *properties)
{
return (CSSGet(properties,"text-decoration-overline") != NULL);
}
int CSSGetDefault(CSSProperties *properties)
{
return DFStringEquals(CSSGet(properties,"-uxwrite-default"),"true");
}
void CSSSetBold(CSSProperties *properties, int value)
{
CSSPut(properties,"font-weight",value ? "bold" : NULL);
}
void CSSSetItalic(CSSProperties *properties, int value)
{
CSSPut(properties,"font-style",value ? "italic" : NULL);
}
void CSSSetUnderline(CSSProperties *properties, int value)
{
CSSPut(properties,"text-decoration-underline",value ? "underline" : NULL);
}
void CSSSetLinethrough(CSSProperties *properties, int value)
{
CSSPut(properties,"text-decoration-line-through",value ? "line-through" : NULL);
}
void CSSSetOverline(CSSProperties *properties, int value)
{
CSSPut(properties,"text-decoration-overline",value ? "overline" : NULL);
}
void CSSSetDefault(CSSProperties *properties, int value)
{
CSSPut(properties,"-uxwrite-default",value ? "true" : NULL);
}
void CSSPropertiesPrint(CSSProperties *properties, const char *indent)
{
const char **allNames = CSSPropertiesCopyNames(properties);
DFSortStringsCaseInsensitive(allNames);
for (int nameIndex = 0; allNames[nameIndex]; nameIndex++) {
const char *name = allNames[nameIndex];
const char *value = CSSGet(properties,name);
printf("%s%s = %s\n",indent,name,value);
}
free(allNames);
}
CSSProperties *CSSPropertiesNewWithExtra(CSSProperties *orig, const char *string)
{
DFHashTable *extra = CSSParseProperties(string);
CSSExpandProperties(extra);
CSSProperties *result = (CSSProperties *)xcalloc(1,sizeof(CSSProperties));
result->retainCount = 1;
result->hashTable = DFHashTableNew((DFCopyFunction)xstrdup,free);
const char **names = DFHashTableCopyKeys(orig->hashTable);
for (int i = 0; names[i]; i++) {
const char *value = DFHashTableLookup(orig->hashTable,names[i]);
DFHashTableAdd(result->hashTable,names[i],(void *)value);
}
free(names);
const char **keys = DFHashTableCopyKeys(extra);
for (int i = 0; keys[i]; i++) {
const char *key = keys[i];
const char *value = DFHashTableLookup(extra,key);
DFHashTableAdd(result->hashTable,key,value);
}
free(keys);
DFHashTableRelease(extra);
return result;
}
CSSProperties *CSSPropertiesNewWithRaw(DFHashTable *raw)
{
CSSProperties *result = (CSSProperties *)xcalloc(1,sizeof(CSSProperties));
result->retainCount = 1;
result->hashTable = DFHashTableNew((DFCopyFunction)xstrdup,free);
if (raw != NULL)
CSSPropertiesUpdateFromRaw(result,raw);
return result;
}
CSSProperties *CSSPropertiesNewWithString(const char *string)
{
DFHashTable *raw = CSSParseProperties(string);
CSSProperties *result = CSSPropertiesNewWithRaw(raw);
DFHashTableRelease(raw);
return result;
}
CSSProperties *CSSPropertiesNew(void)
{
return CSSPropertiesNewWithRaw(NULL);
}
CSSProperties *CSSPropertiesRetain(CSSProperties *properties)
{
if (properties != NULL)
properties->retainCount++;
return properties;
}
void CSSPropertiesRelease(CSSProperties *properties)
{
assert((properties == NULL) || (properties->retainCount > 0));
if ((properties == NULL) || (--properties->retainCount > 0))
return;
assert(properties->changeCallbacks == NULL);
DFHashTableRelease(properties->hashTable);
free(properties);
}