123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- /*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: Details at https://graphviz.org
- *************************************************************************/
- #include <assert.h>
- #include <glcomp/glcomptexture.h>
- #include <glcomp/glpangofont.h>
- #include <stddef.h>
- #include <stdbool.h>
- #include <util/alloc.h>
- #include <util/streq.h>
- static glCompTex *glCompSetAddNewTexture(glCompSet *s, int width, int height,
- const unsigned char *data, bool is2D) {
- int offset, ind;
- unsigned char *tarData;
- if (!data)
- return NULL;
- glCompTex *t = gv_alloc(sizeof(glCompTex));
- if (!is2D) { /*use opengl texture */
- glEnable(GL_TEXTURE_2D);
- glShadeModel(GL_FLAT);
- glEnable(GL_DEPTH_TEST);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glGenTextures(1, &t->id); //get next id
- if (glGetError() != GL_NO_ERROR) { /*for some opengl based error , texture couldnt be created */
- /* drain the OpenGL error queue */
- while (glGetError() != GL_NO_ERROR);
- free(t);
- return NULL;
- } else {
- glBindTexture(GL_TEXTURE_2D, t->id);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
- GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, data);
- glDisable(GL_TEXTURE_2D);
- }
- }
- if (is2D) {
- assert(width >= 0);
- assert(height >= 0);
- t->data = gv_calloc(4 * (unsigned)width * (unsigned)height,
- sizeof(unsigned char));
- offset = 4; //RGBA mod,TO DO implement other modes
- /*data upside down because of pango gl coord system */
- for (ind = 0; ind < height; ind++) {
- const unsigned char *srcData = data + (height - 1 - ind) * offset * width;
- tarData = t->data + ind * offset * width;
- memcpy(tarData, srcData, 4 * (unsigned)width);
- }
- }
- t->userCount = 1;
- t->width = width;
- t->height = height;
- if(s)
- {
- s->textures =
- gv_recalloc(s->textures, s->textureCount, s->textureCount + 1, sizeof(glCompTex *));
- s->textureCount++;
- s->textures[s->textureCount - 1] = t;
- }
- return t;
- }
- glCompTex *glCompSetAddNewTexImage(glCompSet *s, int width, int height,
- const unsigned char *data, bool is2D) {
- glCompTex *t;
- if (!data)
- return NULL;
- t = glCompSetAddNewTexture(s, width, height, data, is2D);
- if (!t)
- return NULL;
- t->type = glTexImage;
- return t;
- }
- glCompTex *glCompSetAddNewTexLabel(glCompSet *s, char *def, int fs, char *text,
- bool is2D) {
- int width, height;
- glCompTex *t;
- cairo_surface_t *surface = NULL;
- unsigned char *data = NULL;
- if (!def)
- return NULL;
- /*first check if the same label with same font def created before
- if it was , return its id
- */
- for (size_t ind = 0; ind < s->textureCount; ind++) {
- if (s->textures[ind]->type == glTexLabel) {
- if (streq(def, s->textures[ind]->def)
- && s->textures[ind]->type == glTexLabel
- && streq(text, s->textures[ind]->text)
- && s->textures[ind]->fontSize==fs) {
- s->textures[ind]->userCount++;
- return s->textures[ind];
- }
- }
- }
- data = glCompCreatePangoTexture(def, fs, text, &surface, &width, &height);
- if (!data) /*pango error , */
- return NULL;
- t = glCompSetAddNewTexture(s, width, height, data, is2D);
- cairo_surface_destroy(surface);
- if (!t) {
- free(data);
- return NULL;
- }
- t->def = gv_strdup(def);
- t->text = gv_strdup(text);
- t->type = glTexLabel;
- return t;
- }
- void glCompDeleteTexture(glCompTex * t)
- {
- if (!t)
- return;
- t->userCount--;
- if (!t->userCount) {
- free(t->data);
- free(t->def);
- free(t->text);
- free(t);
- }
- }
|