Информационный поток
Задания вакансии материалы разработки сообщения форума
Рубрики статей и материалов
Яндекс-директ

Автоматический подбор размера шрифта в объекте РисунокТабличногоДокумента

  • Добавить свою публикацию
  • для этого требуется регистрация

Доброго времени суток, коллеги! Не так давно передо мной встала одна задача, решив которую я подумал, что стоит поделиться опытом. Разработка велась в среде 1с версии 8.2, поэтому я буду использовать соответствующие данной платформе термины.

Итак, суть задачи была в следующем.

Имеем рисунок табличного документа, типа «Надпись». Необходимо реализовать функцию автоматического подбора размера шрифта в данном поле, чтобы текст произвольной длины размещался в нем оптимальным образом, не выходил за границы, и не был бы слишком мелким.

 

Стало быть, само решение:

 

Для начала о настройках свойств самого рисунка табличного документа. Опытным путем установлено, что лучший результат получается при таких значениях свойств:

 

Таблица 1.

Свойство

Значение

РазмещениеТекста

Авто

ГоризонтальноеПоложение

Лево

ВертикальноеПоложение

Центр

 

 

 

 

Теперь о самом принципе.

В целом все, что нужно сделать, - это вычислить физический размер строки символов (в миллиметрах) в высоту и длину.

Рассмотрим этот принцип на примере шрифта Arial, как шрифта по умолчанию в 1С v8.

Я решил, что вернее всего будет взять одну из самых широких букв кириллицы – букву «Ш» - поскольку любой текст в ширину уж точно не будет длиннее, чем текст, состоящий из одних только букв «Ш», и вычислить соотношения ее кегля и физической высоты. Я распечатал эту букву используя шрифт Arial, высотой 100 пунктов, после чего измерил ее высоту и ширину на бумаге в миллиметрах и вычислил соотношение. Честно говоря, я предполагаю, что есть и некий более красивый способ вычислить это соотношение. Однако я такого не нашел, и пошел по простому пути. Как выяснилось, он работает, поэтому прошу не судить строго. Вычислить из расчета 1 пункт = 1/72 дюйма оказалось невозможным, поскольку кегль – величина весьма относительная, как вы знаете, и текст высотой в 100 пунктов, набранный шрифтом Arial будет совсем другой высоты, нежели текст, набранный шрифтом, скажем Colibri, той же высоты кегля.

Вы можете спросить, почему я не использовал букву «Щ», ведь она выше – я отвечу – потому, что выносной элемент не влияет на саму высоту строки, а ведь нам важна именно высота строки, а не самого символа.

Итак, для любого текста в рисунке табличного документа его высота, при оптимальном размещении будет равна (см. рис 1):

 

Hт = 2×Hп + Hш×N+ Hми×N, где

 

Hт– высота текста

Hп– высота поля

Hш– высота шрифта

Hми высота междустрочного интервала

N – количество строк

  

Рисунок 1Изображение

В этой формуле нам еще неизвестны высоты поля Hп и междустрочного интервала Hми

Их также замерил и соотнес с размером шрифта, логично, что это оказались постоянные величины.

Ну, и есть еще такая величина, как длина текста. Она, соответственно, равна ширине символа, умноженной на количество символов в строке. Вы можете подумать, что я забыл про правое и левое поля. Как показала практика, то, что я взял в качестве исходного символа букву «Ш» с лихвой компенсирует эти поля. Хотя, для большей точности, можно ввести и эти коэффициенты. Они, соответственно, вычисляются по тому же принципу, что и коэффициент для верхнего поля – как отношение ширины символа к ширине поля в мм. На самом деле длина текста нужна лишь для вычисления общего количества строк текста. Подробнее – в демонстрационной обработке.

Вот, собственно, и все нужные данные.

Вычисленные значения для шрифта Arial приведены в таблице 2.

 

Таблица 2.

Kвыс

» 0.25

Отношение высоты в мм к высоте в пт

Kшир

» 0.27

Отношение высоты поля в мм к высоте символа в пт

Kполяв

» 0.44

Отношение высоты верхнего поля в мм к высоте символа в мм

Kполял

» 0.4

Отношение ширины левого поля в мм к ширине символа в мм

Kми

» 0.48

Отношение высоты межстрочного интервала в мм к высоте символа в мм

 

 Формулу высоты, для лучшего понимания я перепишу в стиле 1С:

Hп= ВысотаШрифтаММ/КВыс

Hш=ВысотаШрифтаММ

Hми=ВысотаШрифтаММ /КМИ

N= СчСтрокОбщ

 

ВысотаТекста = 2 * ВысотаШрифтаММ*КВыс + ВысотаШрифтаММ*СчСтрокОбщ + ВысотаШрифтаММ*КМИ*СчСтрокОбщ;

отсюда

ВысотаТекста = ВысотаШрифтаММ * (2*КПолей + СчСтрокОбщ * (1 + КМИ));

 

Формула ширины, соответственно

ШиринаТекста = ШиринаТекстаММ * ЧислоСимволов

Ну, или с полями

ШиринаТекста = ШиринаТекстаММ * (ЧислоСимволов + 2 * ТекСтруктураШрифта.КПолейЛев)

 

Конечно, такой метод не особо универсален, но, в принципе такая задача и не актуальна для большого количества разных шрифтов. В моем конкретном случае это был макет ценника, состоящий из множества полей. Там применялся всего один вид шрифта.

Поэтому, я думаю, данное решение может быть полезно во множестве случаев. Если же кто-нибудь укажет мне на большую универсальность расчетов – буду крайне признателен.

 

Обработка, демонстрирующая механизм прилагается.

 

Вот код самой обработки если лень скачивать. 

 

Перем СоответствиеШрифтов;

Процедура ПодобратьШрифт()
	ТабДокумент = ЭлементыФормы.ТабДок;
	Если ТабДокумент.Рисунки.Количество() = 1 Тогда
		ПолеТекста = ТабДокумент.Рисунки[0];
		ШиринаПоляИсх = ПолеТекста.Ширина;
		ВысотаПоляИсх = ПолеТекста.Высота;
		ИсхШрифт      = ПолеТекста.Шрифт;
		//получим соответствующие параметры для данного шрифта
		ТекСтруктураШрифта = СоответствиеШрифтов.Получить(ИсхШрифт.Имя);
		//начинаем с самого мелкого шрифта, и будем увеличивать пока весь текст помещается в пределы поля
		ТекРазмерШрифта = 1;
	    ЧислоСимволов = СтрДлина(ВыбТекст); 		СчСтрок = 0;
		СтрПроверка = "";
		ДлинаТекстаВСтроку = 0;
		Пока Истина Цикл
			СчСтрок = 0;
			СчСтрокОбщ = 0;
			ШиринаТекстаММ = ТекРазмерШрифта * ТекСтруктураШрифта.КШир;
			//подбор ширины, в общем-то, нужен для вычисления количества строк текста
			Для а = 1 По СтрЧислоСтрок(ВыбТекст) Цикл
				СчСтрокОбщ = СчСтрокОбщ + 1;
				ЧислоСимволов = СтрДлина(СтрПолучитьСтроку(ВыбТекст,а));
				//Длина текста равна произведению физической ширины символа на количество символов
				////ДлинаТекстаВСтроку = [ШиринаТекстаММ * ЧислоСимволов] + [2 * ШиринаТекстаММ * ТекСтруктураШрифта.КПолейЛев];
				//ДлинаТекстаВСтроку = ШиринаТекстаММ * (ЧислоСимволов + 2 * ТекСтруктураШрифта.КПолейЛев);
				ДлинаТекстаВСтроку = ШиринаТекстаММ * ЧислоСимволов;
				СчСтрок = СчСтрок + ЦЕЛ(ДлинаТекстаВСтроку/ШиринаПоляИсх);
			КонецЦикла;	
			СчСтрокОбщ = СчСтрокОбщ + СчСтрок;
			////высота текста состоит из:
			////1. верхнего и нижнего поля, они примерно в 2.5 раза меньше высоты шрифта
			////2. высот строк текста - они равны высоте шрифта
			////3. межстрочных интервалов - они примерно в 1.6 раз меньше высоты шрифта
			//// 1 2 3
			////ВысотаТекста = [2 * ВысотаШрифтаММ * КПолей] + [ВысотаШрифтаММ * СчСтрок] + [ВысотаШрифтаММ * СчСтрок * КМИ];
			//итак:
			ВысотаШрифтаММ = ТекРазмерШрифта * ТекСтруктураШрифта.КВыс;
			ВысотаТекста   = ВысотаШрифтаММ * (2*ТекСтруктураШрифта.КПолейВерх + СчСтрокОбщ * (1 + ТекСтруктураШрифта.КМИ));
			
			//все, по высоте не влез - прекращаем
			Если ВысотаТекста >= ВысотаПоляИсх Тогда
				Прервать;
			КонецЕсли;	
			
			ТекРазмерШрифта = ТекРазмерШрифта + 1;
		КонецЦикла;
		//поскольку размер шрифта превысил допустимый отступим на шаг назад
		РезШрифт = Новый Шрифт(ИсхШрифт,,ТекРазмерШрифта-1);
		ПолеТекста.Шрифт = РезШрифт;
		ПолеТекста.Текст = ВыбТекст;
	КонецЕсли;	
КонецПроцедуры	

Процедура КнопкаВыполнитьНажатие(Кнопка)
	ПодобратьШрифт();
КонецПроцедуры

Процедура ПриОткрытии()
	ПодобратьШрифт();
КонецПроцедуры

КВыс       = 0.25;
КШир       = 0.27;
КПолейВерх = 0.44;
КПолейЛев  = 0.4;
КМИ        = 0.6;
ВыбТекст   = "Вы можете менять размеры рисунка и текст. Размер шрифта подбирается нажатием кнопки ""Подогнать""";

СоответствиеШрифтов = Новый Соответствие;
СтруктураПараметровШрифта = Новый Структура("КВыс,КШир,КПолейВерх,КПолейЛев,КМИ",КВыс,КШир,КПолейВерх,КПолейЛев,КМИ);
СоответствиеШрифтов.Вставить("Arial",СтруктураПараметровШрифта);

 

  

 

Спасибо за внимание, надеюсь, статья была полезна.

 

P.S. В интернете также имеется пример решения похожей задачи для ЯчейкиТабличногоДокумента располагается вот здесь

http://infostart.ru/public/123769/

Автор товарищ Александр Гладких - ему спасибо за статью. В ней, кроме всего прочего, упоминается мой метод для рисунка и альтернативный вариант решения, который я попробовал в первую очередь когда озадачился данной проблемой и отверг, поскольку он слишком долго работал при большом количестве многострочного текста.

 
0
Читайте также
Программирование 1с
Программирование 1С это постоянный анализ действующих процессов, подбор методов для решения проблем
Штрихкодирование печатных форм документов в 1С
Штрих-код можно встроить в 1С в любую печатную форму
Настройка 1с
Настройка 1С обеспечит соответствие специфике вашего учета
Разработки
Мульти рассылка СМС из 1С для типовых и не типовых конфигураций, на управляемых и обычных формах
Мультирассылка СМС из 1С для типовых и не типовых конфигураций, на управляемых и обычных формах
Автоматический подбор шрифта в объекте РисунокТабличногоДокумента
Объект табличного документа -автоматический подбор шрифта
Выгрузка данных из УТ 10.3.16.1 в Бухгалтерию 2.0
Обработка для выгрузки данных из УТ 10.3 в БП 2.0
≡ к списку статей