From: John Fultz on
Try this...

TextRect[text_, {{left_, bottom_}, {right_, top_}}] :==
Inset[Pane[text, {Scaled[1], Scaled[1]},
ImageSizeAction -> "ResizeToFit"], {left, bottom}, {Left,
Bottom}, {right - left, top - bottom}]


A tiny demonstration...

Manipulate[
Graphics[{TextRect["some text", {{0, 0}, {1, 1}}],
TextRect["more text", {{5, 5}, {7, 9}}]},
PlotRange -> {{0, n}, {0, n}}, Axes -> True,
GridLines -> Automatic], {n, 1, 100}]

A warning that ImageSizeAction->"ResizeToFit" might not be completely robust.
The problem it's solving is a difficult one, and Mathematica may come up with
solutions which aren't pixel perfect or with slightly unpredictable properties.
For example, the Manipulate demonstrates some slightly unexpected line breaking
properties. But it does generally work, and it's the only way I can think of to
solve your problem without producing some sort of iterative resize-measure sort
of technique.

Sincerely,

John Fultz
jfultz(a)wolfram.com
User Interface Group
Wolfram Research, Inc.


On Thu, 17 Jun 2010 02:03:59 -0400 (EDT), Michael wrote:
> The problem with both of these solutions is that I need the bounding
> rectangle to be in a Graphics[] expression because I'm creating several
> of these text filled boxes at arbitrary offsets. I'm trying to create
> something similar to Graph[] (hopefully using it's embedding functions)
> but instead of vertexes I want to create collections of boxes containing
> text. However Mathematica seems to render text independently of the
> coordinate range of the graphic. For example, these two expressions
> produce identical output:
>
> Graphics[{
> Text[Style["Test", 12]],
> Circle[{0, 0}, 1]
> }
> ]
>
> Graphics[{
> Text[Style["Test", 12]],
> Circle[{0, 0}, 100]
> }
> ]
>
> I found something close to what I want to do, but it's ugly because the
> graphics don't scale nicely:
>
> Graphics[{
> FaceForm[], EdgeForm[Black],
> Raster[Reverse[Rasterize["Hello", "Data"]], {{0, 0}, {100, 16}}],
> Rectangle[{0, 0}, {100, 16}]
> }
> ]
>
> But I would have to hope that surely there is some way to put Text[] in
> Graphics[] such that the size of the text is proportional to the visible
> coordinate range of the Graphics[]. Even if I could only find the size
> of the text in a given image I could then scale it as needed. I tried
> using Rasterize[string,"RasterSize"] but I couldn't figure out how to
> make it work. Any ideas along that line? I'm hoping that I'm just
> missing something obvious that I've overlooked in Mathematica's big API.. .
>
> Thanks,
>
> Michael
>
>
>> On 6/15/2010 2:29 AM, Michael wrote:
>>> How can I automatically scale Text[] to fit into a bounding rectangle
>>> of
>>> a size that I specify?
>>>
>>> For instance, I can get a pretty close result here, but it is not
>>> perfect (the text doesn't touch the bottom edge of the rectangle), and
>>> "36", {0,0}, and {-1,-1} are all numbers I had to find through trial
>>> and
>>> error:
>>>
>>> Graphics[{
>>> FaceForm[], EdgeForm[Black],
>>> Rectangle[{0, 0}, {100, 10}],
>>> Text[Style["Hello", 36], {0, 0}, {-1, -1}]
>>> }
>>> ]
> On 6/16/2010 2:41 AM, Alexei Boulbitch wrote:
>> Hi, Michael,
>>
>> try this:
>>
>> Manipulate[
>>
>> Framed(a)Pane[Graphics[Text[Style["ABcdEG", n]]], {m1, m2},
>> Alignment -> Center],
>>
>> {n, 10, 30}, {m1, 50, 200}, {m2, 20, 200}]
>>
>> and play with parameters to chose those fitting your needs.
>> Have fun, Alexei
> On 6/16/2010 2:42 AM, Helen Read wrote:
>> Framed[Text[Style["Hello"]]]
>>
>> If you want the 36 point font, that's fine too.
>>
>> Framed[Text[Style["Hello", 36]]]
>>
>> You can set FrameMargins on any or all sides.
>>
>> Framed[Text[Style["Hello", 36]], FrameMargins -> {{10, 200}, {0, 0}}]
>>
>> Framed[Text[Style["Hello", 36]], FrameMargins -> 20]


From: Michael on
Thanks John. This looks like it will do what I want.

You are right about the unpredictable properties. When I did a simple
substitution in my code of:
Raster[Reverse[Rasterize["Hello", "Data"]], {{0, 0}, {100, 16}}]
with
TextRect["Hello", {{0,0},{100,16}}]

it all blew up! try just the above line and you should see that you can
no longer scroll at all in the notebook, and there is a tiny weird shape
on the right side of the notebook instead of the usual brackets. It
appears that Inset/Pane can't figure out what to do if Graphics doesn't
have an explicit PlotRange and so it creates output so large the front
end chokes on it.

Hmm... initially it below up inside Graphics[] but it doesn't seem that
I can reproduce this any more without omitting the Graphics[] wrapper.
After some playing around a bit it seems as if my original attempt
somehow made Mathematica unstable and I had to restart. But I still
note that PlotRange->All and PlotRange->Automatic don't figure out the
proper range, and PlotRange->Full outright fails. So now I'll have to
add code to look through all my objects to determine the range. :-)

Thanks everyone for your responses, they have all been very helpful!

Best Regards,

Michael

On 6/17/2010 12:58 AM, John Fultz wrote:
> Try this...
>
> TextRect[text_, {{left_, bottom_}, {right_, top_}}] :=
> Inset[Pane[text, {Scaled[1], Scaled[1]},
> ImageSizeAction -> "ResizeToFit"], {left, bottom}, {Left,
> Bottom}, {right - left, top - bottom}]
>
>
> A tiny demonstration...
>
> Manipulate[
> Graphics[{TextRect["some text", {{0, 0}, {1, 1}}],
> TextRect["more text", {{5, 5}, {7, 9}}]},
> PlotRange -> {{0, n}, {0, n}}, Axes -> True,
> GridLines -> Automatic], {n, 1, 100}]
>
> A warning that ImageSizeAction->"ResizeToFit" might not be completely robust.
> The problem it's solving is a difficult one, and Mathematica may come up with
> solutions which aren't pixel perfect or with slightly unpredictable properties.
> For example, the Manipulate demonstrates some slightly unexpected line breaking
> properties. But it does generally work, and it's the only way I can think of to
> solve your problem without producing some sort of iterative resize-measure sort
> of technique.
>
> Sincerely,
>
> John Fultz
> jfultz(a)wolfram.com
> User Interface Group
> Wolfram Research, Inc.
>
>
> On Thu, 17 Jun 2010 02:03:59 -0400 (EDT), Michael wrote:
>> The problem with both of these solutions is that I need the bounding
>> rectangle to be in a Graphics[] expression because I'm creating several
>> of these text filled boxes at arbitrary offsets. I'm trying to create
>> something similar to Graph[] (hopefully using it's embedding functions)
>> but instead of vertexes I want to create collections of boxes containing
>> text. However Mathematica seems to render text independently of the
>> coordinate range of the graphic. For example, these two expressions
>> produce identical output:
>>
>> Graphics[{
>> Text[Style["Test", 12]],
>> Circle[{0, 0}, 1]
>> }
>> ]
>>
>> Graphics[{
>> Text[Style["Test", 12]],
>> Circle[{0, 0}, 100]
>> }
>> ]
>>
>> I found something close to what I want to do, but it's ugly because the
>> graphics don't scale nicely:
>>
>> Graphics[{
>> FaceForm[], EdgeForm[Black],
>> Raster[Reverse[Rasterize["Hello", "Data"]], {{0, 0}, {100, 16}}],
>> Rectangle[{0, 0}, {100, 16}]
>> }
>> ]
>>
>> But I would have to hope that surely there is some way to put Text[] in
>> Graphics[] such that the size of the text is proportional to the visible
>> coordinate range of the Graphics[]. Even if I could only find the size
>> of the text in a given image I could then scale it as needed. I tried
>> using Rasterize[string,"RasterSize"] but I couldn't figure out how to
>> make it work. Any ideas along that line? I'm hoping that I'm just
>> missing something obvious that I've overlooked in Mathematica's big API...
>>
>> Thanks,
>>
>> Michael
>>
>>
>>> On 6/15/2010 2:29 AM, Michael wrote:
>>>> How can I automatically scale Text[] to fit into a bounding rectangle
>>>> of
>>>> a size that I specify?
>>>>
>>>> For instance, I can get a pretty close result here, but it is not
>>>> perfect (the text doesn't touch the bottom edge of the rectangle), and
>>>> "36", {0,0}, and {-1,-1} are all numbers I had to find through trial
>>>> and
>>>> error:
>>>>
>>>> Graphics[{
>>>> FaceForm[], EdgeForm[Black],
>>>> Rectangle[{0, 0}, {100, 10}],
>>>> Text[Style["Hello", 36], {0, 0}, {-1, -1}]
>>>> }
>>>> ]
>> On 6/16/2010 2:41 AM, Alexei Boulbitch wrote:
>>> Hi, Michael,
>>>
>>> try this:
>>>
>>> Manipulate[
>>>
>>> Framed(a)Pane[Graphics[Text[Style["ABcdEG", n]]], {m1, m2},
>>> Alignment -> Center],
>>>
>>> {n, 10, 30}, {m1, 50, 200}, {m2, 20, 200}]
>>>
>>> and play with parameters to chose those fitting your needs.
>>> Have fun, Alexei
>> On 6/16/2010 2:42 AM, Helen Read wrote:
>>> Framed[Text[Style["Hello"]]]
>>>
>>> If you want the 36 point font, that's fine too.
>>>
>>> Framed[Text[Style["Hello", 36]]]
>>>
>>> You can set FrameMargins on any or all sides.
>>>
>>> Framed[Text[Style["Hello", 36]], FrameMargins -> {{10, 200}, {0, 0}}]
>>>
>>> Framed[Text[Style["Hello", 36]], FrameMargins -> 20]
>
>
>

From: Helen Read on
On 6/17/2010 2:03 AM, Michael wrote:
> The problem with both of these solutions is that I need the bounding
> rectangle to be in a Graphics[] expression because I'm creating several
> of these text filled boxes at arbitrary offsets. I'm trying to create
> something similar to Graph[] (hopefully using it's embedding functions)
> but instead of vertexes I want to create collections of boxes containing
> text. However Mathematica seems to render text independently of the
> coordinate range of the graphic. For example, these two expressions
> produce identical output:

Have you looked at using GraphPlot with a VertexRenderingFunction?

For example:

GraphPlot[{"Hello" -> "World", "World" -> "Planet",
"World" -> "Earth", "Hello" -> "Earth"},
VertexRenderingFunction -> ({White, EdgeForm[{Black, Thick}],
Disk[#, {.2, .1}], Black, Text[#2, #1]} &)]

--
Helen Read
University of Vermont

From: Michael on
Hi Helen,

Thanks for pointing me to the VertexRenderingFunction option. I had
been searching for something like that but I was using the ShowGraph[]
function and did not see that there was a similar function named
GraphPlot[].

Although I will still have to do some tweaking (as I don't want all the
edges to intersect the vertex graphic at a single point) this method
looks like it might be a better way to approach the problem, as it looks
like it will lay out the graph with the extents of the vertexes in mind.

Best Regards,

Michael



On 6/19/2010 4:48 AM, Helen Read wrote:
> On 6/17/2010 2:03 AM, Michael wrote:
>> The problem with both of these solutions is that I need the bounding
>> rectangle to be in a Graphics[] expression because I'm creating several
>> of these text filled boxes at arbitrary offsets. I'm trying to create
>> something similar to Graph[] (hopefully using it's embedding functions)
>> but instead of vertexes I want to create collections of boxes containing
>> text. However Mathematica seems to render text independently of the
>> coordinate range of the graphic. For example, these two expressions
>> produce identical output:
>
> Have you looked at using GraphPlot with a VertexRenderingFunction?
>
> For example:
>
> GraphPlot[{"Hello" -> "World", "World" -> "Planet",
> "World" -> "Earth", "Hello" -> "Earth"},
> VertexRenderingFunction -> ({White, EdgeForm[{Black, Thick}],
> Disk[#, {.2, .1}], Black, Text[#2, #1]}&)]
>
> --
> Helen Read
> University of Vermont
>
>