1. /*
  2. * @(#)BlueprintEngineParser.java 1.12 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing.plaf.gtk;
  8. import java.io.IOException;
  9. import java.util.ArrayList;
  10. import java.awt.Font;
  11. import java.awt.Insets;
  12. import java.awt.Color;
  13. import javax.swing.plaf.synth.SynthConstants;
  14. /**
  15. * A parser for the "blueprint" engine sections in GTK rc theme files.
  16. *
  17. * @author Shannon Hickey
  18. * @version 1.12 12/19/03
  19. */
  20. class BlueprintEngineParser extends GTKEngineParser {
  21. private static final int SYM_IMAGE = GTKScanner.TOKEN_LAST + 1;
  22. private static final int SYM_FUNCTION = SYM_IMAGE + 1;
  23. private static final int SYM_FILE = SYM_FUNCTION + 1;
  24. private static final int SYM_STRETCH = SYM_FILE + 1;
  25. private static final int SYM_RECOLORABLE = SYM_STRETCH + 1;
  26. private static final int SYM_BORDER = SYM_RECOLORABLE + 1;
  27. private static final int SYM_DETAIL = SYM_BORDER + 1;
  28. private static final int SYM_STATE = SYM_DETAIL + 1;
  29. private static final int SYM_SHADOW = SYM_STATE + 1;
  30. private static final int SYM_GAP_SIDE = SYM_SHADOW + 1;
  31. private static final int SYM_GAP_FILE = SYM_GAP_SIDE + 1;
  32. private static final int SYM_GAP_BORDER = SYM_GAP_FILE + 1;
  33. private static final int SYM_GAP_START_FILE = SYM_GAP_BORDER + 1;
  34. private static final int SYM_GAP_START_BORDER = SYM_GAP_START_FILE + 1;
  35. private static final int SYM_GAP_END_FILE = SYM_GAP_START_BORDER + 1;
  36. private static final int SYM_GAP_END_BORDER = SYM_GAP_END_FILE + 1;
  37. private static final int SYM_OVERLAY_FILE = SYM_GAP_END_BORDER + 1;
  38. private static final int SYM_OVERLAY_BORDER = SYM_OVERLAY_FILE + 1;
  39. private static final int SYM_OVERLAY_STRETCH = SYM_OVERLAY_BORDER + 1;
  40. private static final int SYM_ARROW_DIRECTION = SYM_OVERLAY_STRETCH + 1;
  41. private static final int SYM_ORIENTATION = SYM_ARROW_DIRECTION + 1;
  42. private static final int SYM_PARENT_TYPE = SYM_ORIENTATION + 1;
  43. private static final int SYM_COLORIZE_COLOR = SYM_PARENT_TYPE + 1;
  44. private static final int SYM_ICON_COLORIZE = SYM_COLORIZE_COLOR + 1;
  45. private static final int SYM_ICON_COLORIZE_ANCESTOR_TYPE = SYM_ICON_COLORIZE + 1;
  46. private static final int SYM_USE_AS_BKG_MASK = SYM_ICON_COLORIZE_ANCESTOR_TYPE + 1;
  47. private static final int SYM_OVERLAY_RECOLORABLE = SYM_USE_AS_BKG_MASK + 1;
  48. private static final int SYM_OVERLAY_COLORIZE_COLOR = SYM_OVERLAY_RECOLORABLE + 1;
  49. // SYM_D_HLINE and SYM_D_STEPPER are assumed to begin and end the function symbols.
  50. // When adding new symbols, only function symbols should be added between them.
  51. private static final int SYM_D_HLINE = SYM_OVERLAY_COLORIZE_COLOR + 1;
  52. private static final int SYM_D_VLINE = SYM_D_HLINE + 1;
  53. private static final int SYM_D_SHADOW = SYM_D_VLINE + 1;
  54. private static final int SYM_D_POLYGON = SYM_D_SHADOW + 1;
  55. private static final int SYM_D_ARROW = SYM_D_POLYGON + 1;
  56. private static final int SYM_D_DIAMOND = SYM_D_ARROW + 1;
  57. private static final int SYM_D_OVAL = SYM_D_DIAMOND + 1;
  58. private static final int SYM_D_STRING = SYM_D_OVAL + 1;
  59. private static final int SYM_D_BOX = SYM_D_STRING + 1;
  60. private static final int SYM_D_FLAT_BOX = SYM_D_BOX + 1;
  61. private static final int SYM_D_CHECK = SYM_D_FLAT_BOX + 1;
  62. private static final int SYM_D_OPTION = SYM_D_CHECK + 1;
  63. private static final int SYM_D_CROSS = SYM_D_OPTION + 1;
  64. private static final int SYM_D_RAMP = SYM_D_CROSS + 1;
  65. private static final int SYM_D_TAB = SYM_D_RAMP + 1;
  66. private static final int SYM_D_SHADOW_GAP = SYM_D_TAB + 1;
  67. private static final int SYM_D_BOX_GAP = SYM_D_SHADOW_GAP + 1;
  68. private static final int SYM_D_EXTENSION = SYM_D_BOX_GAP + 1;
  69. private static final int SYM_D_FOCUS = SYM_D_EXTENSION + 1;
  70. private static final int SYM_D_SLIDER = SYM_D_FOCUS + 1;
  71. private static final int SYM_D_ENTRY = SYM_D_SLIDER + 1;
  72. private static final int SYM_D_HANDLE = SYM_D_ENTRY + 1;
  73. private static final int SYM_D_LAYOUT = SYM_D_HANDLE + 1;
  74. private static final int SYM_D_BACKGROUND = SYM_D_LAYOUT + 1;
  75. private static final int SYM_D_STEPPER = SYM_D_BACKGROUND + 1;
  76. // end function symbols
  77. private static final int SYM_TRUE = SYM_D_STEPPER + 1;
  78. private static final int SYM_FALSE = SYM_TRUE + 1;
  79. private static final int SYM_TOP = SYM_FALSE + 1;
  80. private static final int SYM_UP = SYM_TOP + 1;
  81. private static final int SYM_BOTTOM = SYM_UP + 1;
  82. private static final int SYM_DOWN = SYM_BOTTOM + 1;
  83. private static final int SYM_LEFT = SYM_DOWN + 1;
  84. private static final int SYM_RIGHT = SYM_LEFT + 1;
  85. private static final int SYM_NORMAL = SYM_RIGHT + 1;
  86. private static final int SYM_ACTIVE = SYM_NORMAL + 1;
  87. private static final int SYM_PRELIGHT = SYM_ACTIVE + 1;
  88. private static final int SYM_SELECTED = SYM_PRELIGHT + 1;
  89. private static final int SYM_INSENSITIVE = SYM_SELECTED + 1;
  90. private static final int SYM_NONE = SYM_INSENSITIVE + 1;
  91. private static final int SYM_IN = SYM_NONE + 1;
  92. private static final int SYM_OUT = SYM_IN + 1;
  93. private static final int SYM_ETCHED_IN = SYM_OUT + 1;
  94. private static final int SYM_ETCHED_OUT = SYM_ETCHED_IN + 1;
  95. private static final int SYM_HORIZONTAL = SYM_ETCHED_OUT + 1;
  96. private static final int SYM_VERTICAL = SYM_HORIZONTAL + 1;
  97. private static final int[] symbolVals = {
  98. SYM_IMAGE, SYM_FUNCTION, SYM_FILE, SYM_STRETCH, SYM_RECOLORABLE,
  99. SYM_BORDER, SYM_DETAIL, SYM_STATE, SYM_SHADOW, SYM_GAP_SIDE,
  100. SYM_GAP_FILE, SYM_GAP_BORDER, SYM_GAP_START_FILE, SYM_GAP_START_BORDER,
  101. SYM_GAP_END_FILE, SYM_GAP_END_BORDER, SYM_OVERLAY_FILE, SYM_OVERLAY_BORDER,
  102. SYM_OVERLAY_STRETCH, SYM_ARROW_DIRECTION, SYM_ORIENTATION,
  103. SYM_PARENT_TYPE, SYM_COLORIZE_COLOR, SYM_ICON_COLORIZE,
  104. SYM_ICON_COLORIZE_ANCESTOR_TYPE, SYM_USE_AS_BKG_MASK,
  105. SYM_OVERLAY_RECOLORABLE, SYM_OVERLAY_COLORIZE_COLOR, SYM_D_HLINE,
  106. SYM_D_VLINE, SYM_D_SHADOW, SYM_D_POLYGON, SYM_D_ARROW, SYM_D_DIAMOND,
  107. SYM_D_OVAL, SYM_D_STRING, SYM_D_BOX, SYM_D_FLAT_BOX, SYM_D_CHECK,
  108. SYM_D_OPTION, SYM_D_CROSS, SYM_D_RAMP, SYM_D_TAB, SYM_D_SHADOW_GAP,
  109. SYM_D_BOX_GAP, SYM_D_EXTENSION, SYM_D_FOCUS, SYM_D_SLIDER, SYM_D_ENTRY,
  110. SYM_D_HANDLE, SYM_D_LAYOUT, SYM_D_BACKGROUND,
  111. SYM_D_STEPPER, SYM_TRUE, SYM_FALSE, SYM_TOP, SYM_UP,
  112. SYM_BOTTOM, SYM_DOWN, SYM_LEFT, SYM_RIGHT, SYM_NORMAL, SYM_ACTIVE,
  113. SYM_PRELIGHT, SYM_SELECTED, SYM_INSENSITIVE, SYM_NONE, SYM_IN, SYM_OUT,
  114. SYM_ETCHED_IN, SYM_ETCHED_OUT, SYM_HORIZONTAL, SYM_VERTICAL
  115. };
  116. private static final String[] symbolNames = {
  117. "image", // SYM_IMAGE
  118. "function", // SYM_FUNCTION
  119. "file", // SYM_FILE
  120. "stretch", // SYM_STRETCH
  121. "recolorable", // SYM_RECOLORABLE
  122. "border", // SYM_BORDER
  123. "detail", // SYM_DETAIL
  124. "state", // SYM_STATE
  125. "shadow", // SYM_SHADOW
  126. "gap_side", // SYM_GAP_SIDE
  127. "gap_file", // SYM_GAP_FILE
  128. "gap_border", // SYM_GAP_BORDER
  129. "gap_start_file", // SYM_GAP_START_FILE
  130. "gap_start_border", // SYM_GAP_START_BORDER
  131. "gap_end_file", // SYM_GAP_END_FILE
  132. "gap_end_border", // SYM_GAP_END_BORDER
  133. "overlay_file", // SYM_OVERLAY_FILE
  134. "overlay_border", // SYM_OVERLAY_BORDER
  135. "overlay_stretch", // SYM_OVERLAY_STRETCH
  136. "arrow_direction", // SYM_ARROW_DIRECTION
  137. "orientation", // SYM_ORIENTATION
  138. "parent_type", // SYM_PARENT_TYPE
  139. "colorize_color", // SYM_COLORIZE_COLOR
  140. "icon_colorize", // SYM_ICON_COLORIZE
  141. "icon_colorize_ancestor_type", // SYM_ICON_COLORIZE_ANCESTOR_TYPE
  142. "use_as_bkg_mask", // SYM_USE_AS_BKG_MASK
  143. "overlay_recolorable", // SYM_OVERLAY_RECOLORABLE
  144. "overlay_colorize_color", // SYM_OVERLAY_COLORIZE_COLOR
  145. "HLINE", // SYM_D_HLINE
  146. "VLINE", // SYM_D_VLINE
  147. "SHADOW", // SYM_D_SHADOW
  148. "POLYGON", // SYM_D_POLYGON
  149. "ARROW", // SYM_D_ARROW
  150. "DIAMOND", // SYM_D_DIAMOND
  151. "OVAL", // SYM_D_OVAL
  152. "STRING", // SYM_D_STRING
  153. "BOX", // SYM_D_BOX
  154. "FLAT_BOX", // SYM_D_FLAT_BOX
  155. "CHECK", // SYM_D_CHECK
  156. "OPTION", // SYM_D_OPTION
  157. "CROSS", // SYM_D_CROSS
  158. "RAMP", // SYM_D_RAMP
  159. "TAB", // SYM_D_TAB
  160. "SHADOW_GAP", // SYM_D_SHADOW_GAP
  161. "BOX_GAP", // SYM_D_BOX_GAP
  162. "EXTENSION", // SYM_D_EXTENSION
  163. "FOCUS", // SYM_D_FOCUS
  164. "SLIDER", // SYM_D_SLIDER
  165. "ENTRY", // SYM_D_ENTRY
  166. "HANDLE", // SYM_D_HANDLE
  167. "LAYOUT", // SYM_D_LAYOUT
  168. "BACKGROUND", // SYM_D_BACKGROUND
  169. "STEPPER", // SYM_D_STEPPER
  170. "TRUE", // SYM_TRUE
  171. "FALSE", // SYM_FALSE
  172. "TOP", // SYM_TOP
  173. "UP", // SYM_UP
  174. "BOTTOM", // SYM_BOTTOM
  175. "DOWN", // SYM_DOWN
  176. "LEFT", // SYM_LEFT
  177. "RIGHT", // SYM_RIGHT
  178. "NORMAL", // SYM_NORMAL
  179. "ACTIVE", // SYM_ACTIVE
  180. "PRELIGHT", // SYM_PRELIGHT
  181. "SELECTED", // SYM_SELECTED
  182. "INSENSITIVE", // SYM_INSENSITIVE
  183. "NONE", // SYM_NONE
  184. "IN", // SYM_IN
  185. "OUT", // SYM_OUT
  186. "ETCHED_IN", // SYM_ETCHED_IN
  187. "ETCHED_OUT", // SYM_ETCHED_OUT
  188. "HORIZONTAL", // SYM_HORIZONTAL
  189. "VERTICAL" // SYM_VERTICAL
  190. };
  191. private static class BlueprintEngineInfo extends GTKParser.EngineInfo {
  192. ArrayList pInfos = new ArrayList();
  193. boolean iconColorize = false;
  194. ArrayList iconAncestorTypes = null;
  195. Color colorizeColor = null;
  196. GTKStyle constructGTKStyle(GTKStyle.GTKStateInfo[] infoArray,
  197. CircularIdentityList props,
  198. Font font,
  199. int xThickness,
  200. int yThickness,
  201. GTKStyle.GTKStockIconInfo[] stockArray) {
  202. BlueprintStyle.Info[] pInfoArray = null;
  203. if (pInfos.size() != 0) {
  204. pInfoArray = new BlueprintStyle.Info[pInfos.size()];
  205. pInfoArray = (BlueprintStyle.Info[])pInfos.toArray(pInfoArray);
  206. }
  207. String[] ancestorArray = null;
  208. if (iconAncestorTypes != null && iconAncestorTypes.size() != 0) {
  209. ancestorArray = new String[iconAncestorTypes.size()];
  210. ancestorArray = (String[])iconAncestorTypes.toArray(ancestorArray);
  211. }
  212. return new BlueprintStyle(infoArray,
  213. props,
  214. font,
  215. xThickness,
  216. yThickness,
  217. stockArray,
  218. pInfoArray,
  219. iconColorize,
  220. ancestorArray,
  221. colorizeColor);
  222. }
  223. }
  224. private GTKScanner scanner;
  225. private GTKParser parser;
  226. private BlueprintEngineInfo engineInfo;
  227. private void registerSymbolsIfNecessary() {
  228. if (scanner.containsSymbol(symbolNames[0])) {
  229. return;
  230. }
  231. for (int i = 0; i < symbolNames.length; i++) {
  232. scanner.addSymbol(symbolNames[i], symbolVals[i]);
  233. }
  234. }
  235. int parse(GTKScanner scanner,
  236. GTKParser parser,
  237. GTKParser.EngineInfo[] retVal) throws IOException {
  238. this.scanner = scanner;
  239. this.parser = parser;
  240. if (retVal[0] == null) {
  241. engineInfo = new BlueprintEngineInfo();
  242. } else {
  243. engineInfo = (BlueprintEngineInfo)retVal[0];
  244. }
  245. int oldScope = scanner.setScope(uniqueScopeID);
  246. registerSymbolsIfNecessary();
  247. BlueprintStyle.Info info[] = new BlueprintStyle.Info[1];
  248. int token;
  249. token = scanner.peekNextToken();
  250. while (token != GTKScanner.TOKEN_RIGHT_CURLY) {
  251. info[0] = null;
  252. switch(token) {
  253. case SYM_IMAGE:
  254. token = parseImage(info);
  255. break;
  256. case SYM_COLORIZE_COLOR:
  257. Color[] col = new Color[1];
  258. token = parseColorizeColor(col);
  259. if (token == GTKScanner.TOKEN_NONE) {
  260. engineInfo.colorizeColor = col[0];
  261. }
  262. break;
  263. case SYM_ICON_COLORIZE:
  264. token = parseIconColorize(engineInfo);
  265. break;
  266. case SYM_ICON_COLORIZE_ANCESTOR_TYPE:
  267. // consume token
  268. scanner.getToken();
  269. if (engineInfo.iconAncestorTypes == null) {
  270. engineInfo.iconAncestorTypes = new ArrayList();
  271. }
  272. token = parseStringList(engineInfo.iconAncestorTypes);
  273. break;
  274. default:
  275. scanner.getToken();
  276. token = GTKScanner.TOKEN_RIGHT_CURLY;
  277. break;
  278. }
  279. if (token != GTKScanner.TOKEN_NONE) {
  280. return token;
  281. }
  282. if (info[0] != null) {
  283. engineInfo.pInfos.add(info[0]);
  284. }
  285. token = scanner.peekNextToken();
  286. }
  287. scanner.getToken();
  288. retVal[0] = engineInfo;
  289. scanner.setScope(oldScope);
  290. return GTKScanner.TOKEN_NONE;
  291. }
  292. private int parseImage(BlueprintStyle.Info[] retVal) throws IOException {
  293. int token;
  294. token = scanner.getToken();
  295. if (token != SYM_IMAGE) {
  296. return SYM_IMAGE;
  297. }
  298. token = scanner.getToken();
  299. if (token != GTKScanner.TOKEN_LEFT_CURLY) {
  300. return GTKScanner.TOKEN_LEFT_CURLY;
  301. }
  302. BlueprintStyle.Info info = new BlueprintStyle.Info();
  303. // to hold the return value from parseFile
  304. String[] fileName = new String[1];
  305. // to hold the return value from parseStretch
  306. // and parseRecolorable
  307. boolean[] bool = new boolean[1];
  308. // to hold the return value from parseBorder
  309. Insets[] insets = new Insets[1];
  310. // to hold the return value from parseColorizeColor
  311. Color[] col = new Color[1];
  312. token = scanner.peekNextToken();
  313. while (token != GTKScanner.TOKEN_RIGHT_CURLY) {
  314. switch(token) {
  315. case SYM_FUNCTION:
  316. token = parseFunction(info);
  317. break;
  318. case SYM_RECOLORABLE:
  319. token = parseRecolorable(bool);
  320. if (token == GTKScanner.TOKEN_NONE) {
  321. info.recolorable = bool[0];
  322. }
  323. break;
  324. case SYM_OVERLAY_RECOLORABLE:
  325. token = parseRecolorable(bool);
  326. if (token == GTKScanner.TOKEN_NONE) {
  327. info.overlayRecolorable = bool[0];
  328. }
  329. break;
  330. case SYM_DETAIL:
  331. token = parseDetail(info);
  332. break;
  333. case SYM_STATE:
  334. token = parseState(info);
  335. break;
  336. case SYM_SHADOW:
  337. token = parseShadow(info);
  338. break;
  339. case SYM_GAP_SIDE:
  340. token = parseGapSide(info);
  341. break;
  342. case SYM_ARROW_DIRECTION:
  343. token = parseArrowDirection(info);
  344. break;
  345. case SYM_ORIENTATION:
  346. token = parseOrientation(info);
  347. break;
  348. case SYM_FILE:
  349. token = parseFile(fileName);
  350. if (token == GTKScanner.TOKEN_NONE) {
  351. info.image = fileName[0];
  352. }
  353. break;
  354. case SYM_BORDER:
  355. token = parseBorder(insets);
  356. if (token == GTKScanner.TOKEN_NONE) {
  357. info.fileInsets = insets[0];
  358. }
  359. break;
  360. case SYM_STRETCH:
  361. token = parseStretch(bool);
  362. if (token == GTKScanner.TOKEN_NONE) {
  363. info.stretch = bool[0];
  364. }
  365. break;
  366. case SYM_GAP_FILE:
  367. token = parseFile(fileName);
  368. if (token == GTKScanner.TOKEN_NONE) {
  369. info.gapImage = fileName[0];
  370. }
  371. break;
  372. case SYM_GAP_BORDER:
  373. token = parseBorder(insets);
  374. if (token == GTKScanner.TOKEN_NONE) {
  375. info.gapInsets = insets[0];
  376. }
  377. break;
  378. case SYM_GAP_START_FILE:
  379. token = parseFile(fileName);
  380. if (token == GTKScanner.TOKEN_NONE) {
  381. info.gapStartImage = fileName[0];
  382. }
  383. break;
  384. case SYM_GAP_START_BORDER:
  385. token = parseBorder(insets);
  386. if (token == GTKScanner.TOKEN_NONE) {
  387. info.gapStartInsets = insets[0];
  388. }
  389. break;
  390. case SYM_GAP_END_FILE:
  391. token = parseFile(fileName);
  392. if (token == GTKScanner.TOKEN_NONE) {
  393. info.gapEndImage = fileName[0];
  394. }
  395. break;
  396. case SYM_GAP_END_BORDER:
  397. token = parseBorder(insets);
  398. if (token == GTKScanner.TOKEN_NONE) {
  399. info.gapEndInsets = insets[0];
  400. }
  401. break;
  402. case SYM_OVERLAY_FILE:
  403. token = parseFile(fileName);
  404. if (token == GTKScanner.TOKEN_NONE) {
  405. info.overlayImage = fileName[0];
  406. }
  407. break;
  408. case SYM_OVERLAY_BORDER:
  409. token = parseBorder(insets);
  410. if (token == GTKScanner.TOKEN_NONE) {
  411. info.overlayInsets = insets[0];
  412. }
  413. break;
  414. case SYM_OVERLAY_STRETCH:
  415. token = parseStretch(bool);
  416. if (token == GTKScanner.TOKEN_NONE) {
  417. info.overlayStretch = bool[0];
  418. }
  419. break;
  420. case SYM_PARENT_TYPE:
  421. // consume token
  422. scanner.getToken();
  423. if (info.parentTypeList == null) {
  424. info.parentTypeList = new ArrayList();
  425. }
  426. token = parseStringList(info.parentTypeList);
  427. break;
  428. case SYM_COLORIZE_COLOR:
  429. token = parseColorizeColor(col);
  430. if (token == GTKScanner.TOKEN_NONE) {
  431. info.colorizeColor = col[0];
  432. }
  433. break;
  434. case SYM_OVERLAY_COLORIZE_COLOR:
  435. token = parseColorizeColor(col);
  436. if (token == GTKScanner.TOKEN_NONE) {
  437. info.overlayColorizeColor = col[0];
  438. }
  439. break;
  440. case SYM_USE_AS_BKG_MASK:
  441. token = parseUseAsBkgMask(info);
  442. break;
  443. default:
  444. scanner.getToken();
  445. token = GTKScanner.TOKEN_RIGHT_CURLY;
  446. break;
  447. }
  448. if (token != GTKScanner.TOKEN_NONE) {
  449. return token;
  450. }
  451. token = scanner.peekNextToken();
  452. }
  453. token = scanner.getToken();
  454. if (token != GTKScanner.TOKEN_RIGHT_CURLY) {
  455. return GTKScanner.TOKEN_RIGHT_CURLY;
  456. }
  457. // PENDING(shannonh) - may want to do some validation of the
  458. // info before we return it
  459. retVal[0] = info;
  460. return GTKScanner.TOKEN_NONE;
  461. }
  462. private int parseFunction(BlueprintStyle.Info info) throws IOException {
  463. int token;
  464. token = scanner.getToken();
  465. if (token != SYM_FUNCTION) {
  466. return SYM_FUNCTION;
  467. }
  468. token = scanner.getToken();
  469. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  470. return GTKScanner.TOKEN_EQUAL_SIGN;
  471. }
  472. token = scanner.getToken();
  473. if (token >= SYM_D_HLINE && token <= SYM_D_STEPPER) {
  474. info.setFunction(symbolNames[token - SYM_IMAGE]);
  475. }
  476. // PENDING(shannonh) - should we complain if not a valid function?
  477. return GTKScanner.TOKEN_NONE;
  478. }
  479. private int parseRecolorable(boolean[] retVal) throws IOException {
  480. int token;
  481. scanner.getToken();
  482. token = scanner.getToken();
  483. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  484. return GTKScanner.TOKEN_EQUAL_SIGN;
  485. }
  486. token = scanner.getToken();
  487. if (token == SYM_TRUE) {
  488. retVal[0] = true;
  489. } else if (token == SYM_FALSE) {
  490. retVal[0] = false;
  491. } else {
  492. return SYM_TRUE;
  493. }
  494. return GTKScanner.TOKEN_NONE;
  495. }
  496. private int parseDetail(BlueprintStyle.Info info) throws IOException {
  497. int token;
  498. token = scanner.getToken();
  499. if (token != SYM_DETAIL) {
  500. return SYM_DETAIL;
  501. }
  502. token = scanner.getToken();
  503. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  504. return GTKScanner.TOKEN_EQUAL_SIGN;
  505. }
  506. token = scanner.getToken();
  507. if (token != GTKScanner.TOKEN_STRING) {
  508. return GTKScanner.TOKEN_STRING;
  509. }
  510. info.setDetail(scanner.currValue.stringVal);
  511. return GTKScanner.TOKEN_NONE;
  512. }
  513. private int parseState(BlueprintStyle.Info info) throws IOException {
  514. int token;
  515. token = scanner.getToken();
  516. if (token != SYM_STATE) {
  517. return SYM_STATE;
  518. }
  519. token = scanner.getToken();
  520. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  521. return GTKScanner.TOKEN_EQUAL_SIGN;
  522. }
  523. token = scanner.getToken();
  524. switch(token) {
  525. case SYM_NORMAL:
  526. info.componentState = SynthConstants.ENABLED;
  527. break;
  528. case SYM_ACTIVE:
  529. info.componentState = SynthConstants.PRESSED;
  530. break;
  531. case SYM_PRELIGHT:
  532. info.componentState = SynthConstants.MOUSE_OVER;
  533. break;
  534. case SYM_SELECTED:
  535. info.componentState = SynthConstants.SELECTED;
  536. break;
  537. case SYM_INSENSITIVE:
  538. info.componentState = SynthConstants.DISABLED;
  539. break;
  540. default:
  541. return SYM_NORMAL;
  542. }
  543. return GTKScanner.TOKEN_NONE;
  544. }
  545. private int parseShadow(BlueprintStyle.Info info) throws IOException {
  546. int token;
  547. token = scanner.getToken();
  548. if (token != SYM_SHADOW) {
  549. return SYM_SHADOW;
  550. }
  551. token = scanner.getToken();
  552. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  553. return GTKScanner.TOKEN_EQUAL_SIGN;
  554. }
  555. token = scanner.getToken();
  556. switch(token) {
  557. case SYM_NONE:
  558. info.shadow = GTKConstants.SHADOW_NONE;
  559. break;
  560. case SYM_IN:
  561. info.shadow = GTKConstants.SHADOW_IN;
  562. break;
  563. case SYM_OUT:
  564. info.shadow = GTKConstants.SHADOW_OUT;
  565. break;
  566. case SYM_ETCHED_IN:
  567. info.shadow = GTKConstants.SHADOW_ETCHED_IN;
  568. break;
  569. case SYM_ETCHED_OUT:
  570. info.shadow = GTKConstants.SHADOW_ETCHED_OUT;
  571. break;
  572. default:
  573. return SYM_NONE;
  574. }
  575. return GTKScanner.TOKEN_NONE;
  576. }
  577. private int parseGapSide(BlueprintStyle.Info info) throws IOException {
  578. int token;
  579. token = scanner.getToken();
  580. if (token != SYM_GAP_SIDE) {
  581. return SYM_GAP_SIDE;
  582. }
  583. token = scanner.getToken();
  584. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  585. return GTKScanner.TOKEN_EQUAL_SIGN;
  586. }
  587. token = scanner.getToken();
  588. switch(token) {
  589. case SYM_TOP:
  590. info.gapSide = GTKConstants.TOP;
  591. break;
  592. case SYM_BOTTOM:
  593. info.gapSide = GTKConstants.BOTTOM;
  594. break;
  595. case SYM_LEFT:
  596. info.gapSide = GTKConstants.LEFT;
  597. break;
  598. case SYM_RIGHT:
  599. info.gapSide = GTKConstants.RIGHT;
  600. break;
  601. default:
  602. return SYM_TOP;
  603. }
  604. return GTKScanner.TOKEN_NONE;
  605. }
  606. private int parseArrowDirection(BlueprintStyle.Info info) throws IOException {
  607. int token;
  608. token = scanner.getToken();
  609. if (token != SYM_ARROW_DIRECTION) {
  610. return SYM_ARROW_DIRECTION;
  611. }
  612. token = scanner.getToken();
  613. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  614. return GTKScanner.TOKEN_EQUAL_SIGN;
  615. }
  616. token = scanner.getToken();
  617. switch(token) {
  618. case SYM_UP:
  619. info.arrowDirection = GTKConstants.ARROW_UP;
  620. break;
  621. case SYM_DOWN:
  622. info.arrowDirection = GTKConstants.ARROW_DOWN;
  623. break;
  624. case SYM_LEFT:
  625. info.arrowDirection = GTKConstants.ARROW_LEFT;
  626. break;
  627. case SYM_RIGHT:
  628. info.arrowDirection = GTKConstants.ARROW_RIGHT;
  629. break;
  630. default:
  631. return SYM_UP;
  632. }
  633. return GTKScanner.TOKEN_NONE;
  634. }
  635. private int parseOrientation(BlueprintStyle.Info info) throws IOException {
  636. int token;
  637. token = scanner.getToken();
  638. if (token != SYM_ORIENTATION) {
  639. return SYM_ORIENTATION;
  640. }
  641. token = scanner.getToken();
  642. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  643. return GTKScanner.TOKEN_EQUAL_SIGN;
  644. }
  645. token = scanner.getToken();
  646. switch(token) {
  647. case SYM_HORIZONTAL:
  648. info.orientation = GTKConstants.HORIZONTAL;
  649. break;
  650. case SYM_VERTICAL:
  651. info.orientation = GTKConstants.VERTICAL;
  652. break;
  653. default:
  654. return SYM_HORIZONTAL;
  655. }
  656. return GTKScanner.TOKEN_NONE;
  657. }
  658. private int parseFile(String[] retVal) throws IOException {
  659. int token;
  660. token = scanner.getToken();
  661. token = scanner.getToken();
  662. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  663. return GTKScanner.TOKEN_EQUAL_SIGN;
  664. }
  665. token = scanner.getToken();
  666. if (token != GTKScanner.TOKEN_STRING) {
  667. return GTKScanner.TOKEN_STRING;
  668. }
  669. retVal[0] = parser.resolvePixmapPath(scanner.currValue.stringVal);
  670. return GTKScanner.TOKEN_NONE;
  671. }
  672. private int parseStretch(boolean[] retVal) throws IOException {
  673. int token;
  674. token = scanner.getToken();
  675. token = scanner.getToken();
  676. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  677. return GTKScanner.TOKEN_EQUAL_SIGN;
  678. }
  679. token = scanner.getToken();
  680. switch(token) {
  681. case SYM_TRUE:
  682. retVal[0] = true;
  683. break;
  684. case SYM_FALSE:
  685. retVal[0] = false;
  686. break;
  687. default:
  688. return SYM_TRUE;
  689. }
  690. return GTKScanner.TOKEN_NONE;
  691. }
  692. private int parseBorder(Insets[] retVal) throws IOException {
  693. int left = 0;
  694. int right = 0;
  695. int top = 0;
  696. int bottom = 0;
  697. scanner.getToken();
  698. if (scanner.getToken() != GTKScanner.TOKEN_EQUAL_SIGN) {
  699. return GTKScanner.TOKEN_EQUAL_SIGN;
  700. }
  701. if (scanner.getToken() != GTKScanner.TOKEN_LEFT_CURLY) {
  702. return GTKScanner.TOKEN_LEFT_CURLY;
  703. }
  704. if (scanner.getToken() != GTKScanner.TOKEN_INT) {
  705. return GTKScanner.TOKEN_INT;
  706. }
  707. left = (int)scanner.currValue.longVal;
  708. if (scanner.getToken() != GTKScanner.TOKEN_COMMA) {
  709. return GTKScanner.TOKEN_COMMA;
  710. }
  711. if (scanner.getToken() != GTKScanner.TOKEN_INT) {
  712. return GTKScanner.TOKEN_INT;
  713. }
  714. right = (int)scanner.currValue.longVal;
  715. if (scanner.getToken() != GTKScanner.TOKEN_COMMA) {
  716. return GTKScanner.TOKEN_COMMA;
  717. }
  718. if (scanner.getToken() != GTKScanner.TOKEN_INT) {
  719. return GTKScanner.TOKEN_INT;
  720. }
  721. top = (int)scanner.currValue.longVal;
  722. if (scanner.getToken() != GTKScanner.TOKEN_COMMA) {
  723. return GTKScanner.TOKEN_COMMA;
  724. }
  725. if (scanner.getToken() != GTKScanner.TOKEN_INT) {
  726. return GTKScanner.TOKEN_INT;
  727. }
  728. bottom = (int)scanner.currValue.longVal;
  729. if (scanner.getToken() != GTKScanner.TOKEN_RIGHT_CURLY) {
  730. return GTKScanner.TOKEN_RIGHT_CURLY;
  731. }
  732. retVal[0] = new Insets(top, left, bottom, right);
  733. return GTKScanner.TOKEN_NONE;
  734. }
  735. private int parseColorizeColor(Color[] retVal) throws IOException {
  736. int token;
  737. scanner.getToken();
  738. token = scanner.getToken();
  739. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  740. return GTKScanner.TOKEN_EQUAL_SIGN;
  741. }
  742. token = scanner.getToken();
  743. switch(token) {
  744. case GTKScanner.TOKEN_LEFT_CURLY:
  745. int red;
  746. int green;
  747. int blue;
  748. int alpha = 255;
  749. token = scanner.getToken();
  750. if (token == GTKScanner.TOKEN_INT) {
  751. red = intColorVal(scanner.currValue.longVal);
  752. } else if (token == GTKScanner.TOKEN_FLOAT) {
  753. red = intColorVal(scanner.currValue.doubleVal);
  754. } else {
  755. return GTKScanner.TOKEN_FLOAT;
  756. }
  757. token = scanner.getToken();
  758. if (token != GTKScanner.TOKEN_COMMA) {
  759. return GTKScanner.TOKEN_COMMA;
  760. }
  761. token = scanner.getToken();
  762. if (token == GTKScanner.TOKEN_INT) {
  763. green = intColorVal(scanner.currValue.longVal);
  764. } else if (token == GTKScanner.TOKEN_FLOAT) {
  765. green = intColorVal(scanner.currValue.doubleVal);
  766. } else {
  767. return GTKScanner.TOKEN_FLOAT;
  768. }
  769. token = scanner.getToken();
  770. if (token != GTKScanner.TOKEN_COMMA) {
  771. return GTKScanner.TOKEN_COMMA;
  772. }
  773. token = scanner.getToken();
  774. if (token == GTKScanner.TOKEN_INT) {
  775. blue = intColorVal(scanner.currValue.longVal);
  776. } else if (token == GTKScanner.TOKEN_FLOAT) {
  777. blue = intColorVal(scanner.currValue.doubleVal);
  778. } else {
  779. return GTKScanner.TOKEN_FLOAT;
  780. }
  781. token = scanner.getToken();
  782. if (token == GTKScanner.TOKEN_COMMA) {
  783. token = scanner.getToken();
  784. if (token == GTKScanner.TOKEN_INT) {
  785. alpha = intColorVal(scanner.currValue.longVal);
  786. } else if (token == GTKScanner.TOKEN_FLOAT) {
  787. alpha = intColorVal(scanner.currValue.doubleVal);
  788. } else {
  789. return GTKScanner.TOKEN_FLOAT;
  790. }
  791. token = scanner.getToken();
  792. }
  793. if (token != GTKScanner.TOKEN_RIGHT_CURLY) {
  794. return GTKScanner.TOKEN_RIGHT_CURLY;
  795. }
  796. retVal[0] = new Color(red, green, blue, alpha);
  797. break;
  798. case GTKScanner.TOKEN_STRING:
  799. Color color = parseColorString(scanner.currValue.stringVal);
  800. if (color == null) {
  801. scanner.printMessage("Invalid color constant '" +
  802. scanner.currValue.stringVal
  803. + "'", false);
  804. return GTKScanner.TOKEN_STRING;
  805. }
  806. retVal[0] = color;
  807. break;
  808. default:
  809. return GTKScanner.TOKEN_STRING;
  810. }
  811. return GTKScanner.TOKEN_NONE;
  812. }
  813. private static Color parseColorString(String str) {
  814. if (str.charAt(0) == '#') {
  815. str = str.substring(1);
  816. int i = str.length();
  817. if (i < 3 || i > 12 || (i % 3) != 0) {
  818. return null;
  819. }
  820. i /= 3;
  821. int r;
  822. int g;
  823. int b;
  824. try {
  825. r = Integer.parseInt(str.substring(0, i), 16);
  826. g = Integer.parseInt(str.substring(i, i * 2), 16);
  827. b = Integer.parseInt(str.substring(i * 2, i * 3), 16);
  828. } catch (NumberFormatException nfe) {
  829. return null;
  830. }
  831. if (i == 4) {
  832. return new Color(r / 65535.0f, g / 65535.0f, b / 65535.0f);
  833. } else if (i == 1) {
  834. return new Color(r / 15.0f, g / 15.0f, b / 15.0f);
  835. } else if (i == 2) {
  836. return new Color(r, g, b);
  837. } else {
  838. return new Color(r / 4095.0f, g / 4095.0f, b / 4095.0f);
  839. }
  840. } else {
  841. return XColors.lookupColor(str);
  842. }
  843. }
  844. private static int intColorVal(long col) {
  845. int color = (int)Math.max(Math.min(col, 255), 0);
  846. return color;
  847. }
  848. private static int intColorVal(double col) {
  849. float color = (float)Math.max(Math.min(col, 1.0f), 0.0f);
  850. return (int)(color * 255);
  851. }
  852. private int parseIconColorize(BlueprintEngineInfo engineInfo) throws IOException {
  853. int token;
  854. token = scanner.getToken();
  855. if (token != SYM_ICON_COLORIZE) {
  856. return SYM_ICON_COLORIZE;
  857. }
  858. token = scanner.getToken();
  859. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  860. return GTKScanner.TOKEN_EQUAL_SIGN;
  861. }
  862. token = scanner.getToken();
  863. if (token == SYM_TRUE) {
  864. engineInfo.iconColorize = true;
  865. } else if (token == SYM_FALSE) {
  866. engineInfo.iconColorize = false;
  867. } else {
  868. return SYM_TRUE;
  869. }
  870. return GTKScanner.TOKEN_NONE;
  871. }
  872. /**
  873. * Helper method for parsing string list assignments such as the following:
  874. * = {"FOO", "BAR", "SJH"}
  875. * The scanner is expected to start returning tokens at the equal sign when
  876. * this method is invoked. It will parse the strings in the list into the
  877. * given <code>ArrayList</code> parameter.
  878. *
  879. * NOTE: The <code>Strings</code> that are added to the
  880. * <code>ArrayList</code> will have been <code>intern()</code>ed
  881. * first.
  882. *
  883. * @return <code>GTKScanner.TOKEN_NONE</code> if the parse was successful,
  884. * otherwise the token that was expected but not received.
  885. */
  886. private int parseStringList(ArrayList list) throws IOException {
  887. int token;
  888. token = scanner.getToken();
  889. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  890. return GTKScanner.TOKEN_EQUAL_SIGN;
  891. }
  892. token = scanner.getToken();
  893. if (token != GTKScanner.TOKEN_LEFT_CURLY) {
  894. return GTKScanner.TOKEN_LEFT_CURLY;
  895. }
  896. token = scanner.getToken();
  897. while (token == GTKScanner.TOKEN_STRING) {
  898. list.add(scanner.currValue.stringVal.intern());
  899. token = scanner.getToken();
  900. if (token == GTKScanner.TOKEN_RIGHT_CURLY) {
  901. continue;
  902. }
  903. if (token != GTKScanner.TOKEN_COMMA) {
  904. return GTKScanner.TOKEN_COMMA;
  905. }
  906. token = scanner.getToken();
  907. }
  908. if (token != GTKScanner.TOKEN_RIGHT_CURLY) {
  909. return GTKScanner.TOKEN_RIGHT_CURLY;
  910. }
  911. return GTKScanner.TOKEN_NONE;
  912. }
  913. private int parseUseAsBkgMask(BlueprintStyle.Info info) throws IOException {
  914. int token;
  915. token = scanner.getToken();
  916. if (token != SYM_USE_AS_BKG_MASK) {
  917. return SYM_USE_AS_BKG_MASK;
  918. }
  919. token = scanner.getToken();
  920. if (token != GTKScanner.TOKEN_EQUAL_SIGN) {
  921. return GTKScanner.TOKEN_EQUAL_SIGN;
  922. }
  923. token = scanner.getToken();
  924. switch(token) {
  925. case SYM_TRUE:
  926. info.useAsBkgMask = true;
  927. break;
  928. case SYM_FALSE:
  929. info.useAsBkgMask = false;
  930. break;
  931. default:
  932. return SYM_TRUE;
  933. }
  934. return GTKScanner.TOKEN_NONE;
  935. }
  936. }