2009-10-19 8 views
2

En utilisant Cairo, je place du texte à des positions aléatoires, et j'ai besoin de savoir si elles chevauchent certaines formes arbitraires précédemment dessinées. Je pourrais couper le chemin vers les dessins précédents, et si un écrêtage se produit, cela signifie qu'il y a chevauchement. Cependant, le Caire ne semble pas avoir de fonctions permettant de savoir si un écrêtage s'est produit ou non.Test Cairo si le texte chevauche

Y at-il un moyen d'accomplir facilement ce que je veux? Je suppose que je veux simplement voir si deux formes se croisent ou non.

Répondre

1

J'ai résolu le problème en utilisant Qt pour le rendu à la place. Il semble avoir une prise en charge assez étendue pour les différentes opérations de chemin et prend en charge les sorties PDF et SVG.

2

Je ne vois rien - au moins, rien de simple - et je ne serais pas surpris s'il n'y avait rien. Le Caire vise à rastériser les opérations de dessin vectoriel, pas les essais d'intersection.

Cependant, si je vais voir si deux morceaux de texte chevauchaient, voici ce que je ferais:

  1. Choisissez un backend Cairo adapté à mon environnement de test - par exemple Xlib, etc. - et utiliser une surface hors écran que je peux utiliser pour faire une analyse pixel par pixel . Dessinez le premier texte en bleu uni avec 100% d'alpha. Dessinez le deuxième texte en rouge uni avec 50% d'alpha.
  2. Balayez la surface pour les pixels où le rouge et le bleu sont non-zéro.

Il s'agit plutôt d'une force brute, mais il va même faire face à l'anti-aliasing. J'ai fait quelque chose comme ça auparavant (dans un but différent) avec GTK sur X, qui utilise indirectement Cairo.

Si vous ne voulez pas le faire ainsi, et que Cairo ne fournit pas d'API, vous pouvez peut-être en ajouter une. Ce serait probablement difficile. vous pourriez vouloir parler avec Carl Worth avant de faire cela.

+0

Eh bien, il y a beaucoup de code de vérification des carrefours au Caire, c'est ce que l'on appelle le découpage, n'est-ce pas? Le code est définitivement là, il n'est simplement pas exposé aux utilisateurs. Je vais aller avec un travail basé sur le raster comme vous le suggérez, mais il semble toujours un peu stupide. Oh, et Cairo n'est pas seulement destiné à la pixellisation, il produit également des formats vectoriels. Je dirais que le Caire est une bibliothèque de dessin vectoriel, et le fait d'avoir à passer par des images raster pour accomplir des choses simples semble un peu stupide. – pafcu

+0

pafcu, je suis d'accord que la route de l'image raster est inélégante. Mais en fonction des besoins, il est parfois préférable d'avoir recours à une solution réalisable, mais inélégante, si elle est plus rapide à mettre en œuvre. J'ai parfois besoin de disposer de disques durs et de m'assurer que les données sensibles qu'ils contiennent ne peuvent pas être lues. L'approche élégante mais longue est une réécriture 7x ou 35x avec des données aléatoires. Au lieu de cela, je les prends juste à mon patio en béton et les frappe à quelques reprises avec un marteau ou une pioche. –

+0

Bob, pouvez-vous s'il vous plaît me rappeler quelle API Cairo fournit cette itération pixel par pixel. J'ai la mémoire c'est là mais je n'ai pas pu le trouver. ADDENDUM: c'est cairo_image_surface_get_data() – akauppi

3

Selon la qualité que vous voulez obtenir, vous pouvez utiliser cairo_stroke_extents, cairo_fill_extents et cairo_text_extents et de travailler sur les boîtes de limite.

Une meilleure approche serait de calculer uniquement la boîte de délimitation du texte et de vérifier les quatre coins par rapport au dernier chemin avec cairo_in_fill ou cairo_in_stroke. L'erreur maximale serait la distance entre la forme d'un seul glyphe et sa boîte englobante, mais peut-être est-ce suffisant pour votre but.

La dernière option serait d'aplatir le texte et de vérifier n'importe quel point comme à l'étape précédente.

+0

Votre suggestion n'est pas assez précise, en tant que telle. Mais merci de pointer vers cairo_in_stroke. En ajustant la largeur de la course pour correspondre aux dimensions de la boîte englobante du texte, un mécanisme suffisamment rapide et solide peut être réalisé. Voir ci-dessous pour ma réponse supplémentaire à ce sujet. Et merci pour le pointeur. :) – akauppi

0

J'ai une situation presque identique et je pense qu'il y a un moyen de le faire.

Mon problème consiste à déterminer si une boîte englobante de texte croise un ensemble complexe de lignes (peut-être lissées) dessinées sur une surface. C'est actuellement un goulot d'étranglement et la gestion rapide des intersections permettrait d'accélérer le sw de 100x peut-être. Qui sait.

De toute façon, grâce à la mention de 0td cairo_in_stroke j'ai commencé à tourner le problème. Voici la chose.

cairo_in_stroke lui-même dit que

« si le point donné est à l'intérieur de la zone qui serait affectée par une opération donnée le chemin courant et les paramètres caressaient cairo_stroke() »

C'est assez inutile. A moins que nous n'effectuions une largeur de ligne si large que le chemin commence à gagner de la place.

  1. ensemble largeur de ligne à la moitié de la hauteur de la zone de délimitation (appelons ce X)
  2. positions d'essai X, 2X, ... dans le cadre de délimitation des deux côtés, jusqu'à ce qu'ils se rejoignent au centre

La zone testée n'est pas précisément la zone de délimitation mais une chaîne de cercles qui se chevauchent. Si vous voulez être du bon côté, l'ajout de largeur de ligne vous assurera que la boîte de délimitation n'est jamais touchée.

Je rapporterai si j'ai obtenu cette méthode pour faire le tour (et à quelle vitesse il est devenu).

Questions connexes