mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-08-25 16:40:14 +03:00
171 lines
3.0 KiB
C
171 lines
3.0 KiB
C
/*
|
|
* text.c - FIG text object
|
|
*
|
|
* Written 2016 by Werner Almesberger
|
|
* Copyright 2016 by Werner Almesberger
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*/
|
|
|
|
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#include "util.h"
|
|
#include "misc.h"
|
|
#include "fig.h"
|
|
#include "text.h"
|
|
|
|
|
|
void text_init(struct text *txt)
|
|
{
|
|
txt->s = NULL;
|
|
txt->size = 0;
|
|
txt->x = txt->y = 0;
|
|
txt->rot = 0;
|
|
txt->hor = text_mid;
|
|
txt->vert = text_mid;
|
|
}
|
|
|
|
|
|
void text_free(struct text *txt)
|
|
{
|
|
free((void *) txt->s);
|
|
txt->s = NULL;
|
|
}
|
|
|
|
|
|
void text_set(struct text *txt, const char *s)
|
|
{
|
|
free((void *) txt->s);
|
|
txt->s = stralloc(s);
|
|
}
|
|
|
|
|
|
void text_rot(struct text *txt, int deg)
|
|
{
|
|
txt->rot = angle_add(txt->rot, deg);
|
|
}
|
|
|
|
|
|
enum text_align text_flip(enum text_align align)
|
|
{
|
|
switch (align) {
|
|
case text_min:
|
|
return text_max;
|
|
case text_mid:
|
|
return text_mid;
|
|
case text_max:
|
|
return text_min;
|
|
default:
|
|
abort();
|
|
}
|
|
}
|
|
|
|
|
|
void text_flip_x(struct text *txt)
|
|
{
|
|
txt->rot = angle_add(txt->rot, 180);
|
|
txt->hor = text_flip(txt->hor);
|
|
// @@@ flip vert, too ?
|
|
}
|
|
|
|
|
|
static int rx(int x, int y, int rot)
|
|
{
|
|
float a = rot / 180.0 * M_PI;
|
|
|
|
return cos(a) * x + sin(a) * y;
|
|
}
|
|
|
|
|
|
static int ry(int x, int y, int rot)
|
|
{
|
|
float a = rot / 180.0 * M_PI;
|
|
|
|
return -sin(a) * x + cos(a) * y;
|
|
}
|
|
|
|
|
|
static int align(int dim, enum text_align align)
|
|
{
|
|
switch (align) {
|
|
case text_min:
|
|
return 0;
|
|
case text_mid:
|
|
return dim / 2;
|
|
case text_max:
|
|
return dim;
|
|
default:
|
|
abort();
|
|
}
|
|
}
|
|
|
|
|
|
void text_fig(const struct text *txt, int color, unsigned layer)
|
|
{
|
|
int x = txt->x;
|
|
int y = txt->y;
|
|
|
|
x += rx(0, align(txt->size, txt->vert), txt->rot);
|
|
y += ry(0, align(txt->size, txt->vert), txt->rot);
|
|
fig_text(x, y, txt->s, txt->size, txt->hor, txt->rot, color, layer);
|
|
}
|
|
|
|
|
|
static unsigned guess_width(const struct text *txt)
|
|
{
|
|
/*
|
|
* Note that fig.c stretches the text size, so the ratio is larger than
|
|
* expressed here.
|
|
*/
|
|
return strlen(txt->s) * txt->size * 1.0;
|
|
}
|
|
|
|
|
|
void text_rel(const struct text *txt, enum text_align xr, enum text_align yr,
|
|
int dx, int dy, int *res_x, int *res_y)
|
|
{
|
|
dx -= align(guess_width(txt), txt->hor);
|
|
dy += align(txt->size, txt->vert);
|
|
dx += align(guess_width(txt), xr);
|
|
dy -= align(txt->size, yr);
|
|
if (res_x)
|
|
*res_x = txt->x + rx(dx, dy, txt->rot);
|
|
if (res_y)
|
|
*res_y = txt->y + ry(dx, dy, txt->rot);
|
|
}
|
|
|
|
|
|
void text_shift(struct text *txt, enum text_align xr, enum text_align yr,
|
|
int dx, int dy)
|
|
{
|
|
text_rel(txt, xr, yr, dx, dy, &txt->x, &txt->y);
|
|
}
|
|
|
|
|
|
int text_rel_x(const struct text *txt, enum text_align xr, enum text_align yr,
|
|
int dx, int dy)
|
|
{
|
|
int x;
|
|
|
|
text_rel(txt, xr, yr, dx, dy, &x, NULL);
|
|
return x;
|
|
}
|
|
|
|
|
|
int text_rel_y(const struct text *txt, enum text_align xr, enum text_align yr,
|
|
int dx, int dy)
|
|
{
|
|
int y;
|
|
|
|
text_rel(txt, xr, yr, dx, dy, NULL, &y);
|
|
return y;
|
|
}
|