Root/eeshow/kicad/lib-render.c

1/*
2 * kicad/lib-render.c - Render component from library
3 *
4 * Written 2016 by Werner Almesberger
5 * Copyright 2016 by Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdlib.h>
15#include <stdio.h>
16#include <assert.h>
17
18#include "misc/util.h"
19#include "misc/diag.h"
20#include "gfx/misc.h"
21#include "gfx/style.h"
22#include "gfx/gfx.h"
23#include "gfx/text.h"
24#include "kicad/sch.h"
25#include "kicad/lib.h"
26
27
28/* ----- Drawing ----------------------------------------------------------- */
29
30
31static void draw_poly(const struct lib_poly *poly, const int m[6])
32{
33    int n = poly->points;
34    int x[n];
35    int y[n];
36    int i;
37
38    for (i = 0; i != n; i++) {
39        x[i] = mx(poly->x[i], poly->y[i], m);
40        y[i] = my(poly->x[i], poly->y[i], m);
41    }
42
43    gfx_poly(n, x, y, COLOR_COMP_DWG, COLOR_NONE, LAYER_COMP_DWG);
44
45    switch (poly->fill) {
46    case 'N':
47        break;
48    case 'F':
49        gfx_poly(n, x, y, COLOR_NONE, COLOR_COMP_DWG,
50            LAYER_COMP_DWG_BG);
51        break;
52    case 'f':
53        gfx_poly(n, x, y, COLOR_NONE, COLOR_COMP_DWG_BG,
54            LAYER_COMP_DWG_BG);
55        break;
56    default:
57        abort();
58    }
59}
60
61
62static void draw_rect(const struct lib_rect *rect, const int m[6])
63{
64    int sx = mx(rect->sx, rect->sy, m);
65    int sy = my(rect->sx, rect->sy, m);
66    int ex = mx(rect->ex, rect->ey, m);
67    int ey = my(rect->ex, rect->ey, m);
68
69    gfx_rect(sx, sy, ex, ey, COLOR_COMP_DWG, COLOR_NONE, LAYER_COMP_DWG);
70
71    switch (rect->fill) {
72    case 'N':
73        break;
74    case 'F':
75        gfx_rect(sx, sy, ex, ey, COLOR_NONE, COLOR_COMP_DWG,
76            LAYER_COMP_DWG_BG);
77        break;
78    case 'f':
79        gfx_rect(sx, sy, ex, ey, COLOR_NONE, COLOR_COMP_DWG_BG,
80            LAYER_COMP_DWG_BG);
81        break;
82    default:
83        abort();
84    }
85}
86
87
88static void draw_circ(const struct lib_circ *circ, const int m[6])
89{
90    int x = mx(circ->x, circ->y, m);
91    int y = my(circ->x, circ->y, m);
92    int r = circ->r;
93
94    gfx_circ(x, y, r, COLOR_COMP_DWG, COLOR_NONE, LAYER_COMP_DWG);
95
96    switch (circ->fill) {
97    case 'N':
98        break;
99    case 'F':
100        gfx_circ(x, y, r, COLOR_NONE, COLOR_COMP_DWG,
101            LAYER_COMP_DWG_BG);
102        break;
103    case 'f':
104        gfx_circ(x, y, r, COLOR_NONE, COLOR_COMP_DWG_BG,
105            LAYER_COMP_DWG_BG);
106        break;
107    default:
108        abort();
109    }
110}
111
112
113static void draw_arc(const struct lib_arc *arc, const int m[6])
114{
115    int a = matrix_to_angle(m);
116    int x = mx(arc->x, arc->y, m);
117    int y = my(arc->x, arc->y, m);
118    int sa = angle_add(arc->start_a, a);
119    int ea = angle_add(arc->end_a, a);
120
121    if (matrix_is_mirrored(m)) {
122        sa = 180 - sa;
123        ea = 180 - ea;
124        while (ea < sa)
125            ea += 360;
126        while (ea - sa > 360)
127            ea -= 360;
128        if (ea - sa >= 180) {
129            swap(sa, ea);
130            sa += 360;
131        }
132    }
133
134    /*
135     * cr_arc (and maybe others) close the arc if filling, so we supply a
136     * foreground color as well. Other objects are closed and don't need
137     * need a foreground color when filling.
138     */
139    switch (arc->fill) {
140    case 'N':
141        break;
142    case 'F':
143        gfx_arc(x, y, arc->r, sa, ea,
144            COLOR_COMP_DWG, COLOR_COMP_DWG, LAYER_COMP_DWG_BG);
145        break;
146    case 'f':
147        gfx_arc(x, y, arc->r, sa, ea,
148            COLOR_COMP_DWG_BG, COLOR_COMP_DWG_BG, LAYER_COMP_DWG_BG);
149        break;
150    default:
151        assert(0);
152    }
153
154    gfx_arc(x, y, arc->r, sa, ea,
155        COLOR_COMP_DWG, COLOR_NONE, LAYER_COMP_DWG);
156}
157
158
159static void draw_pin_name(const struct comp *comp, const struct lib_pin *pin,
160    const int m[6], int dx, int dy, int rot, enum text_align hor)
161{
162    int ox, oy, sx, sy;
163
164    if (!strcmp(pin->name, "~"))
165        return;
166
167    if (comp->name_offset) {
168        ox = dx * (pin->length + comp->name_offset);
169        oy = dy * (pin->length + comp->name_offset);
170        sx = sy = 0;
171    } else {
172        ox = dx * pin->length / 2;
173        oy = dy * pin->length / 2;
174        sx = mxr(-dy * PIN_NUM_OFFSET, dx * PIN_NUM_OFFSET, m);
175        sy = myr(-dy * PIN_NUM_OFFSET, dx * PIN_NUM_OFFSET, m);
176        if (sx > 0)
177            sx = -sx;
178        if (sy > 0)
179            sy = -sy;
180    }
181
182    struct text txt = {
183        .s = pin->name,
184        .x = mx(pin->x + ox, pin->y + oy, m) + sx,
185        .y = my(pin->x + ox, pin->y + oy, m) + sy,
186        .size = pin->name_size,
187        .rot = rot,
188        .hor = comp->name_offset ? hor : text_mid,
189        .vert = comp->name_offset ? text_mid : text_min,
190    };
191
192    text_rot(&txt, matrix_to_angle(m));
193    if (matrix_is_mirrored(m)) {
194        if ((txt.rot % 180) == 0)
195            txt.hor = text_flip(txt.hor);
196        else
197            txt.vert = text_flip(txt.vert);
198    }
199
200    switch (txt.rot) {
201    case 180:
202    case 270:
203        text_flip_x(&txt);
204        break;
205    default:
206        break;
207    }
208
209    text_fig(&txt, COLOR_PIN_NAME, LAYER_PIN_NAME);
210}
211
212
213static void draw_pin_num(const struct comp *comp, const struct lib_pin *pin,
214    const int m[6], int dx, int dy, int rot, enum text_align hor)
215{
216    int ox, oy, sx, sy;
217
218    ox = dx * pin->length / 2;
219    oy = dy * pin->length / 2;
220
221    sx = mxr(-dy * PIN_NUM_OFFSET, dx * PIN_NUM_OFFSET, m);
222    sy = myr(-dy * PIN_NUM_OFFSET, dx * PIN_NUM_OFFSET, m);
223    if (sx > 0)
224        sx = -sx;
225    if (sy > 0)
226        sy = -sy;
227
228    if (!comp->name_offset) {
229        sx = -sx;
230        sy = -sy;
231    }
232
233    struct text txt = {
234        .s = pin->number,
235        .x = mx(pin->x + ox, pin->y + oy, m) + sx,
236        .y = my(pin->x + ox, pin->y + oy, m) + sy,
237        .size = pin->number_size,
238        .rot = rot,
239        .hor = text_mid,
240        .vert = comp->name_offset ? text_min : text_max,
241    };
242
243    text_rot(&txt, matrix_to_angle(m) % 180);
244    if (matrix_is_mirrored(m)) {
245        switch (txt.rot) {
246        case 0:
247            txt.hor = text_flip(txt.hor);
248            break;
249        case 90:
250            break;
251        case 180:
252            txt.hor = text_flip(txt.hor);
253            break;
254        case 270:
255            break;
256        }
257    }
258
259    switch (txt.rot) {
260    case 180:
261    case 270:
262        text_flip_x(&txt);
263        break;
264    default:
265        break;
266    }
267
268    text_fig(&txt, COLOR_PIN_NUMBER, LAYER_PIN_NUMBER);
269}
270
271
272static void draw_pin(const struct comp *comp, const struct lib_pin *pin,
273    const int m[6])
274{
275    int x[2], y[2];
276    int dx = 0, dy = 0;
277    int rot;
278    enum text_align hor;
279
280    switch (pin->orient) {
281    case 'U':
282        dy = 1;
283        rot = 90;
284        hor = text_min;
285        break;
286    case 'D':
287        dy = -1;
288        rot = 90;
289        hor = text_max;
290        break;
291    case 'R':
292        dx = 1;
293        rot = 0;
294        hor = text_min;
295        break;
296    case 'L':
297        dx = -1;
298        rot = 0;
299        hor = text_max;
300        break;
301    default:
302        abort();
303    }
304    x[0] = mx(pin->x, pin->y, m);
305    y[0] = my(pin->x, pin->y, m);
306    x[1] = mx(pin->x + dx * pin->length, pin->y + dy * pin->length, m);
307    y[1] = my(pin->x + dx * pin->length, pin->y + dy * pin->length, m);
308    gfx_poly(2, x, y, COLOR_COMP_DWG, COLOR_NONE, LAYER_COMP_DWG);
309
310    if (comp->show_pin_name)
311        draw_pin_name(comp, pin, m, dx, dy, rot, hor);
312
313    if (comp->show_pin_num)
314        draw_pin_num(comp, pin, m, dx, dy, rot, hor);
315}
316
317
318static void draw_text(const struct lib_text *text, const int m[6])
319{
320    struct text txt = {
321        .s = text->s,
322        .size = text->dim,
323        .x = mx(text->x, text->y, m),
324        .y = my(text->x, text->y, m),
325        .rot = angle_add(text->orient / 10, matrix_to_angle(m)),
326    };
327
328    decode_alignment(&txt, text->hor_align, text->vert_align);
329
330    switch (txt.rot) {
331    case 180:
332    case 270:
333        /* @@@ consolidate this with text_flip_x */
334        txt.rot = angle_add(txt.rot, 180);
335        txt.hor = text_flip(txt.hor);
336        txt.vert = text_flip(txt.vert);
337// text_flip_x(&txt);
338        break;
339    default:
340        break;
341    }
342
343    if (matrix_is_mirrored(m))
344        switch (txt.rot) {
345        case 0:
346        case 180:
347            txt.hor = text_flip(txt.hor);
348            break;
349        case 90:
350        case 270:
351            txt.vert = text_flip(txt.vert);
352            break;
353        default:
354            abort();
355        }
356
357    text_fig(&txt, COLOR_COMP_DWG, WIDTH_COMP_DWG);
358}
359
360
361static void draw(const struct comp *comp, const struct lib_obj *obj,
362    const int m[6])
363{
364    switch (obj->type) {
365    case lib_obj_poly:
366        draw_poly(&obj->u.poly, m);
367        break;
368    case lib_obj_rect:
369        draw_rect(&obj->u.rect, m);
370        break;
371    case lib_obj_circ:
372        draw_circ(&obj->u.circ, m);
373        break;
374    case lib_obj_arc:
375        draw_arc(&obj->u.arc, m);
376        break;
377    case lib_obj_text:
378        draw_text(&obj->u.text, m);
379        break;
380    case lib_obj_pin:
381        draw_pin(comp, &obj->u.pin, m);
382        break;
383    default:
384        abort();
385    }
386}
387
388
389const struct comp *lib_find(const struct lib *lib, const char *name)
390{
391    const struct comp *comp;
392    const struct comp_alias *alias;
393
394    for (comp = lib->comps; comp; comp = comp->next) {
395        if (!strcmp(comp->name, name))
396            return comp;
397        for (alias = comp->aliases; alias; alias = alias->next)
398            if (!strcmp(alias->name, name))
399                return comp;
400    }
401    error("\"%s\" not found", name);
402    return NULL;
403}
404
405
406bool lib_field_visible(const struct comp *comp, int n)
407{
408    return (comp->visible >> n) & 1;
409}
410
411
412static void missing_component(const int m[4])
413{
414    int sx = mx(0, 0, m);
415    int sy = my(0, 0, m);
416    int ex = mx(MISSING_WIDTH, MISSING_HEIGHT, m);
417    int ey = my(MISSING_WIDTH, MISSING_HEIGHT, m);
418
419    gfx_rect(sx, sy, ex, ey, COLOR_MISSING_FG, COLOR_MISSING_BG,
420        LAYER_COMP_DWG);
421}
422
423
424void lib_render(const struct comp *comp, unsigned unit, unsigned convert,
425    const int m[4])
426{
427    const struct lib_obj *obj;
428
429    if (!comp) {
430        missing_component(m);
431        return;
432    }
433    if (!unit)
434        unit = 1;
435    for (obj = comp->objs; obj; obj = obj->next) {
436        if (obj->unit && obj->unit != unit)
437            continue;
438        if (obj->convert && obj->convert != convert)
439            continue;
440        draw(comp, obj, m);
441    }
442}
443

Archive Download this file

Branches:
master



interactive