コード例 #1
0
ファイル: gsub-ligature.c プロジェクト: jojoblack/otfcc
otl_subtable *caryll_read_gsub_ligature(font_file_pointer data, uint32_t tableLength,
                                        uint32_t offset) {
	otl_subtable *_subtable;
	NEW(_subtable);
	subtable_gsub_ligature *subtable = &(_subtable->gsub_ligature);
	subtable->from = NULL;
	subtable->to = NULL;
	checkLength(offset + 6);

	otl_coverage *startCoverage =
	    caryll_read_coverage(data, tableLength, offset + read_16u(data + offset + 2));
	if (!startCoverage) goto FAIL;
	uint16_t setCount = read_16u(data + offset + 4);
	if (setCount != startCoverage->numGlyphs) goto FAIL;
	checkLength(offset + 6 + setCount * 2);

	uint32_t ligatureCount = 0;
	for (uint16_t j = 0; j < setCount; j++) {
		uint32_t setOffset = offset + read_16u(data + offset + 6 + j * 2);
		checkLength(setOffset + 2);
		ligatureCount += read_16u(data + setOffset);
		checkLength(setOffset + 2 + read_16u(data + setOffset) * 2);
	}

	NEW(subtable->to);
	subtable->to->numGlyphs = ligatureCount;
	NEW_N(subtable->to->glyphs, ligatureCount);
	NEW_N(subtable->from, ligatureCount);
	for (uint16_t j = 0; j < ligatureCount; j++) { subtable->from[j] = NULL; };
	uint16_t jj = 0;
	for (uint16_t j = 0; j < setCount; j++) {
		uint32_t setOffset = offset + read_16u(data + offset + 6 + j * 2);
		uint16_t lc = read_16u(data + setOffset);
		for (uint16_t k = 0; k < lc; k++) {
			uint32_t ligOffset = setOffset + read_16u(data + setOffset + 2 + k * 2);
			checkLength(ligOffset + 4);
			uint16_t ligComponents = read_16u(data + ligOffset + 2);
			checkLength(ligOffset + 2 + ligComponents * 2);

			subtable->to->glyphs[jj].gid = read_16u(data + ligOffset);
			subtable->to->glyphs[jj].name = NULL;

			NEW(subtable->from[jj]);
			subtable->from[jj]->numGlyphs = ligComponents;
			NEW_N(subtable->from[jj]->glyphs, ligComponents);
			subtable->from[jj]->glyphs[0].gid = startCoverage->glyphs[j].gid;
			subtable->from[jj]->glyphs[0].name = NULL;
			for (uint16_t m = 1; m < ligComponents; m++) {
				subtable->from[jj]->glyphs[m].gid = read_16u(data + ligOffset + 2 + m * 2);
				subtable->from[jj]->glyphs[m].name = NULL;
			}
			jj++;
		}
	}
	caryll_delete_coverage(startCoverage);
	return _subtable;
FAIL:
	deleteGSUBLigatureSubtable(_subtable);
	return NULL;
}
コード例 #2
0
ファイル: PersonTime.c プロジェクト: kland/person-time
PersonTime_Grid PersonTime_New(const double sigma[], int m, const double tau[], int n)
{
	PersonTime_Grid result;
	int i, j;
	
	assert(m >= 2);
	assert(n >= 2);
	
	NEW(result);
	result->m = m - 1;
	result->n = n - 1;
	NEW_N(result->rect, result->m);
	for (i = 0; i < result->m; i++) {
		NEW_N(result->rect[i], result->n);
		for (j = 0; j < result->n; j++) {
			assert(sigma[i] < sigma[i + 1]);
			result->rect[i][j].sigmaMin = sigma[i];
			result->rect[i][j].sigmaMax = sigma[i + 1];

			assert(tau[j] < tau[j + 1]);
			result->rect[i][j].tauMin = tau[j];
			result->rect[i][j].tauMax = tau[j + 1];
			result->rect[i][j].personTime = 0.0;
		}
	}
	return result;
}
コード例 #3
0
otl_subtable *caryll_read_gpos_mark_to_ligature(font_file_pointer data, uint32_t tableLength,
                                                uint32_t offset) {
	otl_subtable *_subtable;
	NEW(_subtable);
	subtable_gpos_mark_to_ligature *subtable = &(_subtable->gpos_mark_to_ligature);
	if (tableLength < offset + 12) goto FAIL;
	subtable->marks = caryll_read_coverage(data, tableLength, offset + read_16u(data + offset + 2));
	subtable->bases = caryll_read_coverage(data, tableLength, offset + read_16u(data + offset + 4));
	if (!subtable->marks || subtable->marks->numGlyphs == 0 || !subtable->bases ||
	    subtable->bases->numGlyphs == 0)
		goto FAIL;
	subtable->classCount = read_16u(data + offset + 6);
	uint32_t markArrayOffset = offset + read_16u(data + offset + 8);
	subtable->markArray = otl_read_mark_array(data, tableLength, markArrayOffset);
	if (!subtable->markArray || subtable->markArray->markCount != subtable->marks->numGlyphs)
		goto FAIL;

	uint32_t ligArrayOffset = offset + read_16u(data + offset + 10);
	checkLength(ligArrayOffset + 2 + 2 * subtable->bases->numGlyphs);
	if (read_16u(data + ligArrayOffset) != subtable->bases->numGlyphs) goto FAIL;
	NEW_N(subtable->ligArray, subtable->bases->numGlyphs);
	for (uint16_t j = 0; j < subtable->bases->numGlyphs; j++) { subtable->ligArray[j] = NULL; }
	for (uint16_t j = 0; j < subtable->bases->numGlyphs; j++) {
		uint32_t ligAttachOffset = ligArrayOffset + read_16u(data + ligArrayOffset + 2 + j * 2);
		NEW(subtable->ligArray[j]);
		subtable->ligArray[j]->anchors = NULL;
		checkLength(ligAttachOffset + 2);
		subtable->ligArray[j]->componentCount = read_16u(data + ligAttachOffset);

		checkLength(ligAttachOffset + 2 +
		            2 * subtable->ligArray[j]->componentCount * subtable->classCount);
		NEW_N(subtable->ligArray[j]->anchors, subtable->ligArray[j]->componentCount);

		uint32_t _offset = ligAttachOffset + 2;
		for (uint16_t k = 0; k < subtable->ligArray[j]->componentCount; k++) {
			NEW_N(subtable->ligArray[j]->anchors[k], subtable->classCount);
			for (uint16_t m = 0; m < subtable->classCount; m++) {
				uint32_t anchorOffset = read_16u(data + _offset);
				if (anchorOffset) {
					subtable->ligArray[j]->anchors[k][m] =
					    otl_read_anchor(data, tableLength, ligAttachOffset + anchorOffset);
				} else {
					subtable->ligArray[j]->anchors[k][m].present = false;
					subtable->ligArray[j]->anchors[k][m].x = 0;
					subtable->ligArray[j]->anchors[k][m].y = 0;
				}
				_offset += 2;
			}
		}
	}
	goto OK;
FAIL:
	DELETE(delete_mtl_subtable, _subtable);
OK:
	return _subtable;
}
コード例 #4
0
ファイル: gsub-single.c プロジェクト: gitter-badger/otfcc
bool consolidate_gsub_single(caryll_font *font, table_otl *table, otl_subtable *_subtable,
                             sds lookupName) {
	subtable_gsub_single *subtable = &(_subtable->gsub_single);
	consolidate_coverage(font, subtable->from, lookupName);
	consolidate_coverage(font, subtable->to, lookupName);
	uint16_t len =
	    (subtable->from->numGlyphs < subtable->to->numGlyphs ? subtable->from->numGlyphs
	                                                         : subtable->from->numGlyphs);
	gsub_single_map_hash *h = NULL;
	for (uint16_t k = 0; k < len; k++) {
		if (subtable->from->glyphs[k].name && subtable->to->glyphs[k].name) {
			gsub_single_map_hash *s;
			int fromid = subtable->from->glyphs[k].gid;
			HASH_FIND_INT(h, &fromid, s);
			if (s) {
				fprintf(stderr, "[Consolidate] Double-mapping a glyph in a "
				                "single substitution /%s.\n",
				        subtable->from->glyphs[k].name);
			} else {
				NEW(s);
				s->fromid = subtable->from->glyphs[k].gid;
				s->toid = subtable->to->glyphs[k].gid;
				s->fromname = subtable->from->glyphs[k].name;
				s->toname = subtable->to->glyphs[k].name;
				HASH_ADD_INT(h, fromid, s);
			}
		}
	}
	HASH_SORT(h, by_from_id);
	if (HASH_COUNT(h) != subtable->from->numGlyphs || HASH_COUNT(h) != subtable->to->numGlyphs) {
		fprintf(stderr, "[Consolidate] In single subsitution lookup %s, some "
		                "mappings are ignored.\n",
		        lookupName);
	}
	subtable->from->numGlyphs = HASH_COUNT(h);
	subtable->to->numGlyphs = HASH_COUNT(h);
	FREE(subtable->from->glyphs);
	FREE(subtable->to->glyphs);
	NEW_N(subtable->from->glyphs, subtable->from->numGlyphs);
	NEW_N(subtable->to->glyphs, subtable->to->numGlyphs);
	{
		gsub_single_map_hash *s, *tmp;
		uint16_t j = 0;
		HASH_ITER(hh, h, s, tmp) {
			subtable->from->glyphs[j].gid = s->fromid;
			subtable->from->glyphs[j].name = s->fromname;
			subtable->to->glyphs[j].gid = s->toid;
			subtable->to->glyphs[j].name = s->toname;
			j++;
			HASH_DEL(h, s);
			free(s);
		}
	}
コード例 #5
0
ファイル: gsub-ligature.c プロジェクト: jojoblack/otfcc
caryll_buffer *caryll_write_gsub_ligature_subtable(otl_subtable *_subtable) {
	caryll_buffer *buf = bufnew();
	subtable_gsub_ligature *subtable = &(_subtable->gsub_ligature);
	ligature_aggerator *h = NULL, *s, *tmp;
	uint16_t nLigatures = subtable->to->numGlyphs;
	for (uint16_t j = 0; j < nLigatures; j++) {
		int sgid = subtable->from[j]->glyphs[0].gid;
		HASH_FIND_INT(h, &sgid, s);
		if (!s) {
			NEW(s);
			s->gid = sgid;
			s->ligid = HASH_COUNT(h);
			HASH_ADD_INT(h, gid, s);
		}
	}
	HASH_SORT(h, by_gid);

	otl_coverage *startCoverage;
	NEW(startCoverage);
	startCoverage->numGlyphs = HASH_COUNT(h);
	NEW_N(startCoverage->glyphs, startCoverage->numGlyphs);

	uint16_t jj = 0;
	foreach_hash(s, h) {
		s->ligid = jj;
		startCoverage->glyphs[jj].gid = s->gid;
		startCoverage->glyphs[jj].name = NULL;
		jj++;
	}
コード例 #6
0
static void parseBases(json_value *_bases, subtable_gpos_mark_to_ligature *subtable,
                       classname_hash **h) {
	uint16_t classCount = HASH_COUNT(*h);
	NEW(subtable->bases);
	subtable->bases->numGlyphs = _bases->u.object.length;
	NEW_N(subtable->bases->glyphs, subtable->bases->numGlyphs);
	NEW_N(subtable->ligArray, _bases->u.object.length);
	for (uint16_t j = 0; j < _bases->u.object.length; j++) {
		subtable->bases->glyphs[j].name =
		    sdsnewlen(_bases->u.object.values[j].name, _bases->u.object.values[j].name_length);
		NEW(subtable->ligArray[j]);
		subtable->ligArray[j]->componentCount = 0;
		subtable->ligArray[j]->anchors = NULL;

		json_value *baseRecord = _bases->u.object.values[j].value;
		if (!baseRecord || baseRecord->type != json_array) continue;
		subtable->ligArray[j]->componentCount = baseRecord->u.array.length;

		NEW_N(subtable->ligArray[j]->anchors, subtable->ligArray[j]->componentCount);

		for (uint16_t k = 0; k < subtable->ligArray[j]->componentCount; k++) {
			json_value *_componentRecord = baseRecord->u.array.values[k];
			NEW_N(subtable->ligArray[j]->anchors[k], classCount);
			for (uint16_t m = 0; m < classCount; m++) {
				subtable->ligArray[j]->anchors[k][m] = otl_anchor_absent();
			}
			if (!_componentRecord || _componentRecord->type != json_object) { continue; }
			for (uint16_t m = 0; m < _componentRecord->u.object.length; m++) {
				sds className = sdsnewlen(_componentRecord->u.object.values[m].name,
				                          _componentRecord->u.object.values[m].name_length);
				classname_hash *s;
				HASH_FIND_STR(*h, className, s);
				if (!s) goto NEXT;
				subtable->ligArray[j]->anchors[k][s->classID] =
				    otl_anchor_from_json(_componentRecord->u.object.values[m].value);

			NEXT:
				sdsfree(className);
			}
		}
	}
}
コード例 #7
0
ファイル: gsub-ligature.c プロジェクト: jojoblack/otfcc
otl_subtable *caryll_gsub_ligature_from_json(json_value *_subtable) {
	otl_subtable *_st;
	NEW(_st);
	subtable_gsub_ligature *st = &(_st->gsub_ligature);
	NEW(st->to);
	st->to->numGlyphs = _subtable->u.object.length;
	NEW_N(st->to->glyphs, st->to->numGlyphs);
	NEW_N(st->from, st->to->numGlyphs);

	uint16_t jj = 0;
	for (uint16_t k = 0; k < st->to->numGlyphs; k++) {
		json_value *_from = _subtable->u.object.values[k].value;
		if (!_from || _from->type != json_array) continue;
		st->to->glyphs[jj].name = sdsnewlen(_subtable->u.object.values[k].name,
		                                    _subtable->u.object.values[k].name_length);
		st->from[jj] = caryll_coverage_from_json(_from);
		jj += 1;
	}
	st->to->numGlyphs = jj;
	return _st;
}
コード例 #8
0
static void parseMarks(json_value *_marks, subtable_gpos_mark_to_ligature *subtable,
                       classname_hash **h) {
	NEW(subtable->marks);
	subtable->marks->numGlyphs = _marks->u.object.length;
	NEW_N(subtable->marks->glyphs, subtable->marks->numGlyphs);
	NEW(subtable->markArray);
	subtable->markArray->markCount = _marks->u.object.length;
	NEW_N(subtable->markArray->records, subtable->markArray->markCount);
	for (uint16_t j = 0; j < _marks->u.object.length; j++) {
		char *gname = _marks->u.object.values[j].name;
		json_value *anchorRecord = _marks->u.object.values[j].value;
		subtable->marks->glyphs[j].name = sdsnewlen(gname, _marks->u.object.values[j].name_length);

		subtable->markArray->records[j].markClass = 0;
		subtable->markArray->records[j].anchor = otl_anchor_absent();

		if (!anchorRecord || anchorRecord->type != json_object) continue;
		json_value *_className = json_obj_get_type(anchorRecord, "class", json_string);
		if (!_className) continue;

		sds className = sdsnewlen(_className->u.string.ptr, _className->u.string.length);
		classname_hash *s;
		HASH_FIND_STR(*h, className, s);
		if (!s) {
			NEW(s);
			s->className = className;
			s->classID = HASH_COUNT(*h);
			HASH_ADD_STR(*h, className, s);
		} else {
			sdsfree(className);
		}
		subtable->markArray->records[j].markClass = s->classID;
		subtable->markArray->records[j].anchor.present = true;
		subtable->markArray->records[j].anchor.x = json_obj_getnum(anchorRecord, "x");
		subtable->markArray->records[j].anchor.y = json_obj_getnum(anchorRecord, "y");
	}
}
コード例 #9
0
ファイル: main.c プロジェクト: Julow/libft
int				main(void)
{
	t_set			set;
	t_test *const	nodes = NEW_N(t_test, TEST_SIZE);

	set = SET(&test_cmp, 0);

	{
		uint32_t		i;
		uint32_t		occur;

		i = 0;
		while (i < TEST_SIZE)
		{
			nodes[i] = TEST(ft_rand(-TEST_SIZE/2, TEST_SIZE/2));
			occur = count_occur(&set, nodes[i].key);
			ft_set_insert(&set, &nodes[i], &nodes[i].key);
			ASSERT(occur == count_occur(&set, nodes[i].key) - 1, "INSERT ERROR");
			i++;
		}
	}

	ASSERT(test_order_count(&set) == TEST_SIZE, "COUNT ERROR");
	test_get(&set);
	test_begin(&set);
	ASSERT(max_height(set.root) <= min_height(set.root) * 2, "BALANCE ERROR");
	TRACE("INSERT OK");

	t_vec2u			range;

	range.x = ft_rand(0, TEST_SIZE / 2);
	range.y = ft_rand(TEST_SIZE / 2, TEST_SIZE);

	{
		uint32_t		i;
		uint32_t		occur;

		i = range.x;
		while (i < range.y)
		{
			occur = count_occur(&set, nodes[i].key);
			ft_set_remove(&set, &nodes[i]);
			ASSERT(occur == count_occur(&set, nodes[i].key) + 1, "REMOVE ERROR");
			i++;
		}
	}

	test_order_count(&set);
	test_get(&set);
	test_begin(&set);
	ASSERT(max_height(set.root) <= min_height(set.root) * 2, "BALANCE ERROR");
	TRACE("REMOVE OK");

	{
		uint32_t		i;

		i = range.y;
		while (--i >= range.x)
		{
			nodes[i].key = range.x;
			ft_set_insert(&set, &nodes[i], &nodes[i].key);
		}
	}

	test_order_count(&set);
	test_get(&set);
	test_begin(&set);
	ASSERT(max_height(set.root) <= min_height(set.root) * 2, "BALANCE ERROR");
	TRACE("INSERT REV SORTED OK");

	{
		uint32_t		i;

		i = 0;
		while (i < TEST_SIZE)
		{
			ft_set_remove(&set, &nodes[0]);
			nodes[0].key = i;
			ft_set_insert(&set, &nodes[0], &nodes[0].key);
			i++;
		}
	}

	test_order_count(&set);
	test_get(&set);
	test_begin(&set);
	ASSERT(max_height(set.root) <= min_height(set.root) * 2, "BALANCE ERROR");
	TRACE("INSERT SORTED OK");

	{

#define DUP_COUNT		100000

		uint32_t		i;
		t_test			*before;
		t_test			*tmp;
		t_test *const	insert = NEW_N(t_test, DUP_COUNT);

		before = ft_set_get(&set, &nodes[ft_rand(0, TEST_SIZE - 1)].key);

		i = 0;
		while (i < DUP_COUNT)
		{
			while ((tmp = ft_set_prev(before)) != NULL && tmp->key == before->key)
				before = tmp;
			insert[i] = TEST(before->key - 1);
			ft_set_insert_before(&set, &insert[i], before);
			tmp = ft_set_prev(before);
			ASSERT(tmp == &insert[i], "INSERT_BEFORE (prev) ERROR");
			tmp = ft_set_next(&insert[i]);
			ASSERT(tmp == before, "INSERT_BEFORE (next) ERROR");
			before = &insert[i];
			i++;
		}

	}

	test_order_count(&set);
	test_get(&set);
	test_begin(&set);
	ASSERT(max_height(set.root) <= min_height(set.root) * 2, "BALANCE ERROR");
	TRACE("INSERT_BEFORE OK");

	// print_tree(set.root);
	// print_iter(&set);

	return (0);
}